storyteller / app.py
abdull4h's picture
Update app.py
92842f7 verified
import gradio as gr
import time
import random
# This import will fail unless your environment includes the internal "spaces" module
try:
import spaces
except ImportError:
raise ImportError(
"Could not import 'spaces'. The @spaces.GPU decorator is likely not available in your environment.\n"
"To use GPU, create an empty 'gpu' file in your Space or enable GPU in Space Settings."
)
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
# CSS for custom styling with RTL support
custom_css = """
.gradio-container {
background: linear-gradient(to bottom right, #1a1a2e, #16213e);
}
.container {
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
padding: 20px;
background-color: #0f3460;
margin-bottom: 20px;
}
footer {
color: #e94560 !important;
}
.story-output textarea {
background-color: #16213e !important;
border-radius: 10px !important;
padding: 15px !important;
font-family: 'Arial', sans-serif !important;
line-height: 1.8 !important;
color: #ffffff !important;
direction: rtl !important; /* Right-to-left for Arabic */
text-align: right !important;
font-size: 16px !important;
}
.example-btn button {
background-color: #e94560 !important;
color: white !important;
}
.info-text {
font-size: 0.9em;
color: #cccccc;
}
.title {
text-align: center;
color: #e94560 !important;
font-size: 2.5em !important;
margin-bottom: 0;
}
.subtitle {
text-align: center;
color: #cccccc !important;
font-size: 1.2em !important;
margin-top: 5px;
}
/* RTL support for prompt input */
.rtl-text textarea {
direction: rtl !important;
text-align: right !important;
font-size: 16px !important;
}
"""
# Load the model and tokenizer
print("Loading model and tokenizer...")
model_name = "ALLaM-AI/ALLaM-7B-Instruct-preview"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False)
model = AutoModelForCausalLM.from_pretrained(model_name)
# Move model to GPU immediately
model.to("cuda")
# Create a pipeline
generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)
# Example prompts for the user to try (in Arabic)
example_prompts = [
"في عالم حيث يمكن مشاركة الأحلام، يكتشف محقق شاب أن قاتلًا متسلسلًا يستخدم الأحلام لاصطياد ضحاياه...",
"يكتشف شقيقان خريطة قديمة في علية جدتهما تقودهما إلى عالم سحري مخفي في الغابة خلف منزلهما...",
"طباخ لديه القدرة على تذوق المشاعر في الطعام يُحضّر وجبة لزبون غامض يبدو أنه بلا مشاعر على الإطلاق...",
"بعد حدث عالمي تسبب في توقف جميع التكنولوجيا عن العمل، تكتشف مجموعة من المراهقين أن لديهم قدرات جديدة غريبة...",
"يصل مسافر عبر الزمن إلى يومنا الحاضر مع تحذير عاجل، لكن لا أحد يصدقه لأن...",
]
# Story genres for the dropdown (in Arabic)
story_genres = [
"مغامرة",
"خيال",
"خيال علمي",
"غموض",
"رومانسية",
"رعب",
"كوميديا",
"دراما",
"حكاية خيالية",
"مستقبل قاتم"
]
# Decorate the function that needs GPU with @spaces.GPU
@spaces.GPU
def generate_story(prompt, max_length=300, temperature=0.7, top_p=0.9, genre="مغامرة", creativity_level="متوسط"):
"""
Generate a story based on the user's prompt and specified parameters.
GPU is allocated only while this function is running in ZeroGPU environments.
"""
# Enhance the prompt with the genre and creativity instructions (in Arabic)
creativity_map = {
"تقليدي": "اكتب قصة تقليدية ومباشرة من نوع",
"متوسط": "اكتب قصة إبداعية وجذابة من نوع",
"إبداعي": "اكتب قصة خيالية وفريدة من نوع"
}
enhanced_prompt = f"{creativity_map.get(creativity_level, 'اكتب قصة جذابة من نوع')} {genre}: {prompt}"
# Generate the story
response = generator(
enhanced_prompt,
max_length=max_length,
temperature=float(temperature),
top_p=float(top_p),
do_sample=True
)
generated_text = response[0]["generated_text"]
# Format the story to start from where the prompt ends
if generated_text.startswith(enhanced_prompt):
formatted_story = generated_text[len(enhanced_prompt):].strip()
else:
formatted_story = generated_text
# Return the generated story
return formatted_story
# Function to get a random example prompt
def get_random_example():
return random.choice(example_prompts)
# Function to update the UI based on creativity level
def update_creativity_params(creativity):
if creativity == "تقليدي":
return 0.5, 0.85
elif creativity == "متوسط":
return 0.7, 0.9
elif creativity == "إبداعي":
return 0.9, 0.95
return 0.7, 0.9
# Main function for Gradio interface
def create_interface():
with gr.Blocks(css=custom_css) as demo:
# Title and subtitle (in Arabic)
gr.HTML("<h1 class='title'>✨ مولد القصص الذكي ✨</h1>")
gr.HTML("<p class='subtitle'>أطلق العنان لخيالك مع سرد القصص بمساعدة الذكاء الاصطناعي</p>")
# Input section
with gr.Row():
with gr.Column():
gr.HTML("<div class='container'>")
prompt = gr.Textbox(
placeholder="أدخل بداية قصتك هنا...",
label="بداية القصة",
lines=5,
elem_classes=["rtl-text"] # Add RTL class
)
with gr.Row():
genre = gr.Dropdown(
choices=story_genres,
value="مغامرة",
label="نوع القصة"
)
creativity = gr.Radio(
choices=["تقليدي", "متوسط", "إبداعي"],
value="متوسط",
label="مستوى الإبداع"
)
with gr.Accordion("إعدادات متقدمة", open=False):
with gr.Row():
temperature = gr.Slider(
minimum=0.1,
maximum=1.0,
step=0.05,
value=0.7,
label="درجة الحرارة"
)
top_p = gr.Slider(
minimum=0.5,
maximum=1.0,
step=0.05,
value=0.9,
label="Top-P"
)
max_length = gr.Slider(
minimum=100,
maximum=1500,
step=50,
value=500,
label="الحد الأقصى لطول القصة"
)
gr.HTML("<div class='info-text' dir='rtl'><p>✨ <strong>نصائح لبدايات قصص رائعة:</strong> كن محددًا، أضف شخصيات وإعدادات وصراعات.</p></div>")
with gr.Row():
submit_btn = gr.Button("توليد القصة", variant="primary")
with gr.Column(elem_classes=["example-btn"]):
example_btn = gr.Button("جرب مثالًا")
gr.HTML("</div>") # Close container div
# Output section
with gr.Row():
with gr.Column():
gr.HTML("<div class='container'>")
output = gr.Textbox(
label="قصتك",
lines=12,
elem_classes=["story-output"]
)
gr.HTML("<div class='info-text' style='text-align: center; margin-top: 10px;' dir='rtl'><p>💡 كل قصة يتم إنشاؤها بشكل فريد وقد تختلف في الأسلوب والمحتوى.</p></div>")
gr.HTML("</div>") # Close container div
# Set up the submit action
submit_btn.click(
fn=generate_story,
inputs=[prompt, max_length, temperature, top_p, genre, creativity],
outputs=[output]
)
# Get random example when button is clicked
example_btn.click(
fn=get_random_example,
outputs=[prompt]
)
# Update parameters based on creativity level
creativity.change(
fn=update_creativity_params,
inputs=[creativity],
outputs=[temperature, top_p]
)
gr.HTML("<div style='text-align: center; margin-top: 20px; color: #cccccc;' dir='rtl'><p>مدعوم بواسطة ALLaM-7B-Instruct • تم إنشاؤه باستخدام Gradio</p></div>")
return demo
# Launch the app
if __name__ == "__main__":
demo = create_interface()
demo.launch()