StoryTeller / app.py
GhalaDev's picture
Update app.py
858f1b4 verified
Raw History Blame Contribute Delete
3.56 kB
import spaces
import gradio as gr
import torch
from transformers import (
BlipProcessor,
BlipForConditionalGeneration,
AutoTokenizer,
AutoModelForCausalLM,
)
APP_TITLE = "StoryLens AI"
STORY_STYLES = [
"Fantasy",
"Adventure",
"Mystery",
"Sci-Fi",
"Inspirational",
"Comedy",
"Historical",
]
DEFAULT_STYLE = STORY_STYLES[0]
device = "cuda" if torch.cuda.is_available() else "cpu"
dtype = torch.float16 if device == "cuda" else torch.float32
blip_id = "Salesforce/blip-image-captioning-base"
caption_processor = BlipProcessor.from_pretrained(blip_id)
caption_model = BlipForConditionalGeneration.from_pretrained(
blip_id,
torch_dtype=dtype,
).to(device)
llm_id = "Qwen/Qwen2.5-1.5B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(llm_id)
story_model = AutoModelForCausalLM.from_pretrained(
llm_id,
torch_dtype=dtype,
).to(device)
@spaces.GPU
def generate_caption(image):
inputs = caption_processor(
image,
return_tensors="pt"
).to(device, dtype)
output = caption_model.generate(
**inputs,
max_new_tokens=30
)
return caption_processor.decode(
output[0],
skip_special_tokens=True
)
@spaces.GPU
def generate_story(caption, style, max_tokens):
prompt = (
f"Create an engaging story inspired by this image description: '{caption}'. "
f"Use the '{style}' style. "
"The story should be creative, descriptive, and between 3 and 5 sentences."
)
messages = [
{
"role": "user",
"content": prompt
}
]
inputs = tokenizer.apply_chat_template(
messages,
add_generation_prompt=True,
return_tensors="pt",
return_dict=False,
).to(device)
outputs = story_model.generate(
inputs,
max_new_tokens=max_tokens,
do_sample=True,
temperature=0.8,
top_p=0.9,
pad_token_id=tokenizer.eos_token_id,
)
return tokenizer.decode(
outputs[0][inputs.shape[1]:],
skip_special_tokens=True,
)
def generate_output(image, style, length):
if image is None:
return "Please upload an image first.", ""
image = image.convert("RGB")
caption = generate_caption(image)
story = generate_story(
caption,
style,
length,
)
return caption, story
custom_theme = gr.themes.Default(
primary_hue="blue",
secondary_hue="blue",
neutral_hue="slate",
)
css = """
body{
background:#0f172a;
}
.gradio-container{
background:#0f172a !important;
}
footer{
display:none;
}
"""
demo = gr.Interface(
fn=generate_output,
inputs=[
gr.Image(
type="pil",
label="Upload Image"
),
gr.Dropdown(
choices=STORY_STYLES,
value=DEFAULT_STYLE,
label="Story Style"
),
gr.Slider(
minimum=40,
maximum=200,
value=120,
step=10,
label="Story Length"
),
],
outputs=[
gr.Textbox(
label="Image Caption"
),
gr.Textbox(
label="Generated Story",
lines=8
),
],
title=APP_TITLE,
description="""
Upload any image and let AI first describe it, then transform that description
into a creative story based on your selected writing style.
""",
theme=custom_theme,
css=css,
)
demo.launch(server_name="0.0.0.0", server_port=7860)