Sunil Surendra Singh commited on
Commit
3253a7e
1 Parent(s): 65f6ddd

added genre and story style input params

Browse files
Files changed (6) hide show
  1. README.md +3 -1
  2. app.py +82 -33
  3. assets/story-teller-app.png +2 -2
  4. assets/story-teller-examples.png +2 -2
  5. config.py +35 -0
  6. model.py +16 -8
README.md CHANGED
@@ -30,7 +30,7 @@ BLIP Image2Text model details can be found [here](https://huggingface.co/Sof22/i
30
 
31
  * It's important to note that this sample demonstration app is hosted on the free tiers of Huggingface Spaces, which means it is functional but may exhibit slower performance.
32
  * Additionally, when using the app for the first time or after an extended period (more than 1 hour), you might encounter an "Internal Error" message or receive a story unrelated to the provided image. This is a normal occurrence during the model loading process. Please wait a few seconds and try again; it should function as intended.
33
- * Please be aware that due to cost and resource constraints, the app currently has a maximum story length limit of 100 words per request.
34
 
35
  App UI is shown below:
36
 
@@ -38,6 +38,8 @@ App UI is shown below:
38
 
39
  **Dark Mode Toggle**: Activate it to switch between dark and light mode.
40
  **Image Selector**: Click on it to pick an image from your computer, or drag and drop an image onto it directly. Click the 'X' to clear the selection and resets the app.
 
 
41
  **Story Length (in words) Slider**: Adjust the slider to specify the desired length of the generated story.
42
  **Creativity Index Slider**: Modify the slider to indicate the desired level of creativity for the generated story. A range between 0.5 and 0.7 is recommended. Setting it to 1.0 results in highly creative, sometimes amusing output.
43
  **Generate Story Button**: Press this button to initiate the story generation process.
 
30
 
31
  * It's important to note that this sample demonstration app is hosted on the free tiers of Huggingface Spaces, which means it is functional but may exhibit slower performance.
32
  * Additionally, when using the app for the first time or after an extended period (more than 1 hour), you might encounter an "Internal Error" message or receive a story unrelated to the provided image. This is a normal occurrence during the model loading process. Please wait a few seconds and try again; it should function as intended.
33
+ * Please be aware that due to cost and resource constraints, the app currently has a maximum story length limit of 200 words per request.
34
 
35
  App UI is shown below:
36
 
 
38
 
39
  **Dark Mode Toggle**: Activate it to switch between dark and light mode.
40
  **Image Selector**: Click on it to pick an image from your computer, or drag and drop an image onto it directly. Click the 'X' to clear the selection and resets the app.
41
+ **Story Genre Dropdown**: Select the desired story genre from the dropdown list.
42
+ **Story Writing Style Dropdown**: Select the desired story writing style from the dropdown list.
43
  **Story Length (in words) Slider**: Adjust the slider to specify the desired length of the generated story.
44
  **Creativity Index Slider**: Modify the slider to indicate the desired level of creativity for the generated story. A range between 0.5 and 0.7 is recommended. Setting it to 1.0 results in highly creative, sometimes amusing output.
45
  **Generate Story Button**: Press this button to initiate the story generation process.
app.py CHANGED
@@ -30,21 +30,25 @@ def create_interface():
30
  api_name=False,
31
  )
32
  with gr.Row():
33
- with gr.Column(scale=5):
34
  gr.Markdown(
35
  """
36
- # Storyteller
37
  **This app can craft captivating narratives from captivating images,
38
- potentially surpassing even Shakespearean standards. Select an image
39
- that inspires a story, choose a story length (up to 100 words), and
40
- adjust the creativity index to enhance its creative flair.**
 
 
 
 
41
  <br>
42
- ***Please exercise patience, as the models employed are extensive and may
43
- require a few seconds to load. If you encounter an unrelated story,
44
- it is likely still loading; wait a moment and try again.***
45
  """
46
  )
47
- with gr.Column(scale=2):
48
  max_count = gr.Textbox(
49
  label="Max allowed OpenAI requests:",
50
  value=app_config.openai_max_access_count,
@@ -63,21 +67,34 @@ def create_interface():
63
  image = gr.Image(
64
  type="filepath",
65
  )
66
- # Word Count Slider
67
- word_count = gr.Slider(
68
- label="Story Length (words):",
69
- minimum=25,
70
- maximum=100,
71
- value=50,
72
- step=5,
73
- )
74
- creativity = gr.Slider(
75
- label="Creativity Index:",
76
- minimum=0.3,
77
- maximum=1.0,
78
- value=0.7,
79
- step=0.1,
80
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  with gr.Row():
82
  submit_button = gr.Button(
83
  value="Generate Story", elem_classes="orange-button"
@@ -87,24 +104,56 @@ def create_interface():
87
  story = gr.Textbox(
88
  label="Story:",
89
  placeholder="Generated story will appear here.",
90
- lines=12,
91
  )
92
  with gr.Row():
93
  with gr.Accordion("Expand for examples:", open=False):
94
  gr.Examples(
95
  examples=[
96
- ["assets/examples/cheetah-deer.jpg", 50, 0.5],
97
- ["assets/examples/man-child-pet-dog.jpg", 100, 0.6],
98
- ["assets/examples/man-child.jpeg", 60, 1.0],
99
- ["assets/examples/men-fighting.jpg", 50, 0.4],
100
- ["assets/examples/teacher-school.jpg", 80, 0.7],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  ],
102
- inputs=[image, word_count, creativity],
103
- outputs=[story],
 
 
104
  )
105
  submit_button.click(
106
  fn=model.generate_story,
107
- inputs=[image, word_count, creativity],
108
  outputs=[story, max_count, curr_count, available_count],
109
  )
110
  clear_button.click(
 
30
  api_name=False,
31
  )
32
  with gr.Row():
33
+ with gr.Column():
34
  gr.Markdown(
35
  """
36
+ # The Storyteller
37
  **This app can craft captivating narratives from captivating images,
38
+ potentially surpassing even Shakespearean standards.
39
+ <br>
40
+ Select an `Image` that inspires a story, choose a `Story Genre`,
41
+ `Story Writing Style`, `Story Length (up to 200 words)`, and
42
+ adjust the `Creativity Index` to enhance its creative flair. Then
43
+ hit `Generate Story` button.
44
+ Alternatively, just select one the pre-configured `Examples`**
45
  <br>
46
+ ***Please exercise patience, as the models employed are extensive
47
+ and may require a few seconds to load. If you encounter an unrelated
48
+ story, it is likely still loading; wait a moment and try again.***
49
  """
50
  )
51
+ with gr.Column():
52
  max_count = gr.Textbox(
53
  label="Max allowed OpenAI requests:",
54
  value=app_config.openai_max_access_count,
 
67
  image = gr.Image(
68
  type="filepath",
69
  )
70
+ with gr.Row():
71
+ with gr.Column():
72
+ genre = gr.Dropdown(
73
+ label="Story Genre: ",
74
+ value="Poetry",
75
+ choices=app_config.genre,
76
+ )
77
+ style = gr.Dropdown(
78
+ label="Story Writing Style:",
79
+ value="Cinematic",
80
+ choices=app_config.writing_style_list,
81
+ )
82
+ with gr.Column():
83
+ # Word Count Slider
84
+ word_count = gr.Slider(
85
+ label="Story Length (words):",
86
+ minimum=30,
87
+ maximum=200,
88
+ value=50,
89
+ step=10,
90
+ )
91
+ creativity = gr.Slider(
92
+ label="Creativity Index:",
93
+ minimum=0.3,
94
+ maximum=1.0,
95
+ value=0.7,
96
+ step=0.1,
97
+ )
98
  with gr.Row():
99
  submit_button = gr.Button(
100
  value="Generate Story", elem_classes="orange-button"
 
104
  story = gr.Textbox(
105
  label="Story:",
106
  placeholder="Generated story will appear here.",
107
+ lines=21,
108
  )
109
  with gr.Row():
110
  with gr.Accordion("Expand for examples:", open=False):
111
  gr.Examples(
112
  examples=[
113
+ [
114
+ "assets/examples/cheetah-deer.jpg",
115
+ "Horror",
116
+ "Narrative",
117
+ 80,
118
+ 0.5,
119
+ ],
120
+ [
121
+ "assets/examples/man-child-pet-dog.jpg",
122
+ "Fiction",
123
+ "Formal",
124
+ 100,
125
+ 0.6,
126
+ ],
127
+ [
128
+ "assets/examples/man-child.jpeg",
129
+ "Children Literature",
130
+ "Symbolic",
131
+ 120,
132
+ 1.0,
133
+ ],
134
+ [
135
+ "assets/examples/men-fighting.jpg",
136
+ "Comedy",
137
+ "Experimental",
138
+ 60,
139
+ 0.4,
140
+ ],
141
+ [
142
+ "assets/examples/teacher-school.jpg",
143
+ "Surrealism",
144
+ "Non-linear",
145
+ 80,
146
+ 0.7,
147
+ ],
148
  ],
149
+ fn=model.generate_story,
150
+ inputs=[image, genre, style, word_count, creativity],
151
+ outputs=[story, max_count, curr_count, available_count],
152
+ run_on_click=True,
153
  )
154
  submit_button.click(
155
  fn=model.generate_story,
156
+ inputs=[image, genre, style, word_count, creativity],
157
  outputs=[story, max_count, curr_count, available_count],
158
  )
159
  clear_button.click(
assets/story-teller-app.png CHANGED

Git LFS Details

  • SHA256: 81eb678baf1bffb86c0cf04c0c53b13d0bc9dd29f9e86213af3ce5755e0ceeeb
  • Pointer size: 131 Bytes
  • Size of remote file: 325 kB

Git LFS Details

  • SHA256: 1b31a834ba86e0fa0a38b89580672c60ff613ccefe0bb672f9ef253d34a386df
  • Pointer size: 131 Bytes
  • Size of remote file: 341 kB
assets/story-teller-examples.png CHANGED

Git LFS Details

  • SHA256: f00754c24db0a5e2d622f075284a5d95ef47a5a9dab8dfe0774a0a4e12b5d405
  • Pointer size: 131 Bytes
  • Size of remote file: 105 kB

Git LFS Details

  • SHA256: e51fcaa6b124469059532e06391f744f1f933e8af160c5ba92759bb7c1a53d72
  • Pointer size: 131 Bytes
  • Size of remote file: 104 kB
config.py CHANGED
@@ -17,6 +17,41 @@ class AppConfig:
17
  OPENAI_KEY = os.getenv("OPENAI_KEY")
18
  I2T_API_URL = os.getenv("I2T_API_URL")
19
  MONGO_CONN_STR = os.getenv("MONGO_CONN_STR")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
 
22
  app_config = AppConfig()
 
17
  OPENAI_KEY = os.getenv("OPENAI_KEY")
18
  I2T_API_URL = os.getenv("I2T_API_URL")
19
  MONGO_CONN_STR = os.getenv("MONGO_CONN_STR")
20
+ genre_list = genre = [
21
+ "Adventure",
22
+ "Children Literature",
23
+ "Comedy",
24
+ "Drama",
25
+ "Fantasy",
26
+ "Fiction",
27
+ "Horror",
28
+ "Mystery",
29
+ "Non-fiction",
30
+ "Poetry",
31
+ "Romance",
32
+ "Satire",
33
+ "Surrealism",
34
+ "Urban Fantasy",
35
+ ]
36
+ writing_style_list = [
37
+ "Cinematic",
38
+ "Conversational",
39
+ "Descriptive",
40
+ "Experimental",
41
+ "First-Person",
42
+ "Formal",
43
+ "Informal",
44
+ "Metaphorical",
45
+ "Minimalist",
46
+ "Narrative",
47
+ "Non-linear",
48
+ "Objective",
49
+ "Sensory",
50
+ "Stream of Consciousness",
51
+ "Symbolic",
52
+ "Third-Person Limited",
53
+ "Third-Person Omniscient",
54
+ ]
55
 
56
 
57
  app_config = AppConfig()
model.py CHANGED
@@ -22,7 +22,7 @@ def __image2text(image):
22
  return response
23
 
24
 
25
- def __text2story(image_desc, word_count, creativity):
26
  """ "Generates a short story based on image description text prompt"""
27
  ## chat LLM model
28
  story_model = ChatOpenAI(
@@ -32,13 +32,15 @@ def __text2story(image_desc, word_count, creativity):
32
  )
33
  ## chat message prompts
34
  sys_prompt = PromptTemplate(
35
- template="You are an expert storyteller that can generate"
36
- + " imaginative {word_count} words long story from the input text",
37
- input_variables=["word_count"],
 
 
38
  )
39
  system_msg_prompt = SystemMessagePromptTemplate(prompt=sys_prompt)
40
  human_prompt = PromptTemplate(
41
- template="{image_desc}", input_variables=["image_desc"]
42
  )
43
  human_msg_prompt = HumanMessagePromptTemplate(prompt=human_prompt)
44
  chat_prompt = ChatPromptTemplate.from_messages(
@@ -46,11 +48,13 @@ def __text2story(image_desc, word_count, creativity):
46
  )
47
  ## LLM chain
48
  story_chain = LLMChain(llm=story_model, prompt=chat_prompt)
49
- response = story_chain.run(image_desc=image_desc, word_count=word_count)
 
 
50
  return response
51
 
52
 
53
- def generate_story(image_file, word_count, creativity):
54
  """Generates a story given an image"""
55
  # read image as bytes arrayS
56
  with open(image_file, "rb") as f:
@@ -59,7 +63,11 @@ def generate_story(image_file, word_count, creativity):
59
  image_desc = __image2text(image=input_image)
60
  # generate story from caption
61
  story = __text2story(
62
- image_desc=image_desc, word_count=word_count, creativity=creativity
 
 
 
 
63
  )
64
  # increment the openai access counter and compute count stats
65
  mongo.increment_curr_access_count()
 
22
  return response
23
 
24
 
25
+ def __text2story(image_desc, genre, style, word_count, creativity):
26
  """ "Generates a short story based on image description text prompt"""
27
  ## chat LLM model
28
  story_model = ChatOpenAI(
 
32
  )
33
  ## chat message prompts
34
  sys_prompt = PromptTemplate(
35
+ template="""You are an expert story writer, write a maximum of {word_count}
36
+ words long story in {genre} genre in {style} writing style, based on the user
37
+ provided story-context.
38
+ """,
39
+ input_variables=["word_count", "genre", "style"],
40
  )
41
  system_msg_prompt = SystemMessagePromptTemplate(prompt=sys_prompt)
42
  human_prompt = PromptTemplate(
43
+ template="story-context: {context}", input_variables=["context"]
44
  )
45
  human_msg_prompt = HumanMessagePromptTemplate(prompt=human_prompt)
46
  chat_prompt = ChatPromptTemplate.from_messages(
 
48
  )
49
  ## LLM chain
50
  story_chain = LLMChain(llm=story_model, prompt=chat_prompt)
51
+ response = story_chain.run(
52
+ genre=genre, style=style, word_count=word_count, context=image_desc
53
+ )
54
  return response
55
 
56
 
57
+ def generate_story(image_file, genre, style, word_count, creativity):
58
  """Generates a story given an image"""
59
  # read image as bytes arrayS
60
  with open(image_file, "rb") as f:
 
63
  image_desc = __image2text(image=input_image)
64
  # generate story from caption
65
  story = __text2story(
66
+ image_desc=image_desc,
67
+ genre=genre,
68
+ style=style,
69
+ word_count=word_count,
70
+ creativity=creativity,
71
  )
72
  # increment the openai access counter and compute count stats
73
  mongo.increment_curr_access_count()