second
Browse files- app.py +94 -80
- requirements.txt +2 -2
app.py
CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
|
|
2 |
import logging
|
3 |
import sys
|
4 |
import os
|
|
|
5 |
|
6 |
# Configure logging
|
7 |
logging.basicConfig(
|
@@ -15,100 +16,113 @@ logger = logging.getLogger(__name__)
|
|
15 |
logger.info("Starting StudAI Summarization Service with Gradio")
|
16 |
logger.info(f"Python version: {sys.version}")
|
17 |
|
18 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
try:
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
summarizer = pipeline(
|
24 |
-
"summarization",
|
25 |
-
model=
|
26 |
-
device
|
|
|
27 |
)
|
|
|
28 |
logger.info("Model loaded successfully!")
|
29 |
model_available = True
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
except Exception as e:
|
31 |
logger.error(f"Failed to load model: {str(e)}")
|
32 |
-
|
33 |
-
|
34 |
def summarize_text(text, max_length=150, min_length=30):
|
35 |
-
"""Summarize the provided text
|
|
|
|
|
|
|
36 |
try:
|
37 |
-
if
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
if not model_available:
|
41 |
-
return "Error: Summarization model is not available"
|
42 |
-
|
43 |
-
logger.info(f"Summarizing text of length {len(text)}")
|
44 |
-
result = summarizer(
|
45 |
-
text,
|
46 |
-
max_length=max_length,
|
47 |
-
min_length=min_length,
|
48 |
-
truncation=True
|
49 |
-
)
|
50 |
-
summary = result[0]["summary_text"]
|
51 |
-
logger.info(f"Generated summary of length {len(summary)}")
|
52 |
return summary
|
53 |
except Exception as e:
|
54 |
logger.error(f"Error during summarization: {str(e)}")
|
55 |
-
|
56 |
-
|
57 |
-
def api_summarize(text, max_length=150, min_length=30):
|
58 |
-
"""API function for summarization"""
|
59 |
-
summary = summarize_text(text, max_length, min_length)
|
60 |
-
return {"summary": summary}
|
61 |
|
62 |
# Create Gradio interface
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
min_length = gr.Slider(
|
83 |
-
label="Min Length",
|
84 |
-
minimum=10,
|
85 |
-
maximum=200,
|
86 |
-
value=30,
|
87 |
-
step=5
|
88 |
-
)
|
89 |
-
submit_btn = gr.Button("Summarize")
|
90 |
-
|
91 |
-
with gr.Column():
|
92 |
-
output_text = gr.Textbox(label="Summary", lines=10)
|
93 |
-
|
94 |
-
submit_btn.click(
|
95 |
-
fn=summarize_text,
|
96 |
-
inputs=[input_text, max_length, min_length],
|
97 |
-
outputs=output_text
|
98 |
-
)
|
99 |
-
|
100 |
-
# Add API endpoints for Android app
|
101 |
-
gr.Interface(
|
102 |
-
fn=api_summarize,
|
103 |
-
inputs=[
|
104 |
-
gr.Textbox(label="text"),
|
105 |
-
gr.Number(label="max_length", default=150),
|
106 |
-
gr.Number(label="min_length", default=30)
|
107 |
-
],
|
108 |
-
outputs=gr.JSON(),
|
109 |
-
title="Summarization API",
|
110 |
-
description="API for StudAI Android app"
|
111 |
-
).launch(show_api=True)
|
112 |
|
113 |
-
# Launch
|
114 |
-
demo.launch()
|
|
|
2 |
import logging
|
3 |
import sys
|
4 |
import os
|
5 |
+
import gc
|
6 |
|
7 |
# Configure logging
|
8 |
logging.basicConfig(
|
|
|
16 |
logger.info("Starting StudAI Summarization Service with Gradio")
|
17 |
logger.info(f"Python version: {sys.version}")
|
18 |
|
19 |
+
# Force garbage collection
|
20 |
+
gc.collect()
|
21 |
+
|
22 |
+
# Create a simple function for summarization that doesn't use ML in case model loading fails
|
23 |
+
def simple_summarize(text, max_length=150, min_length=30):
|
24 |
+
"""Simple extractive summarization as fallback"""
|
25 |
+
import re
|
26 |
+
sentences = re.split(r'(?<=[.!?])\s+', text)
|
27 |
+
|
28 |
+
if len(sentences) <= 3:
|
29 |
+
return text
|
30 |
+
|
31 |
+
# Take first, middle and last sentences
|
32 |
+
summary = [
|
33 |
+
sentences[0],
|
34 |
+
sentences[len(sentences) // 2],
|
35 |
+
sentences[-1]
|
36 |
+
]
|
37 |
+
return " ".join(summary)
|
38 |
+
|
39 |
+
# Set a flag for model availability
|
40 |
+
model_available = False
|
41 |
+
|
42 |
+
# Try to import and load the model with memory optimizations
|
43 |
try:
|
44 |
+
# Import and load only when needed
|
45 |
+
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline
|
46 |
+
import torch
|
47 |
+
|
48 |
+
logger.info("Loading small model for summarization...")
|
49 |
|
50 |
+
# Use a tiny model instead of t5-small
|
51 |
+
model_name = "facebook/bart-large-cnn"
|
52 |
+
|
53 |
+
# Enable memory optimization
|
54 |
+
if torch.cuda.is_available():
|
55 |
+
logger.info("CUDA available, using GPU")
|
56 |
+
device = 0
|
57 |
+
else:
|
58 |
+
logger.info("CUDA not available, using CPU")
|
59 |
+
device = -1
|
60 |
+
|
61 |
+
# Enable memory-efficient loading
|
62 |
summarizer = pipeline(
|
63 |
+
"summarization",
|
64 |
+
model=model_name,
|
65 |
+
device=device,
|
66 |
+
framework="pt"
|
67 |
)
|
68 |
+
|
69 |
logger.info("Model loaded successfully!")
|
70 |
model_available = True
|
71 |
+
|
72 |
+
# Force garbage collection after model loading
|
73 |
+
gc.collect()
|
74 |
+
if torch.cuda.is_available():
|
75 |
+
torch.cuda.empty_cache()
|
76 |
+
|
77 |
except Exception as e:
|
78 |
logger.error(f"Failed to load model: {str(e)}")
|
79 |
+
logger.info("Will use simple extractive summarization instead")
|
80 |
+
|
81 |
def summarize_text(text, max_length=150, min_length=30):
|
82 |
+
"""Summarize the provided text"""
|
83 |
+
if not text or len(text.strip()) < 50:
|
84 |
+
return text
|
85 |
+
|
86 |
try:
|
87 |
+
if model_available:
|
88 |
+
logger.info(f"Summarizing text of length {len(text)} with model")
|
89 |
+
result = summarizer(
|
90 |
+
text,
|
91 |
+
max_length=max_length,
|
92 |
+
min_length=min_length,
|
93 |
+
truncation=True
|
94 |
+
)
|
95 |
+
summary = result[0]["summary_text"]
|
96 |
+
else:
|
97 |
+
logger.info(f"Using simple summarization for text of length {len(text)}")
|
98 |
+
summary = simple_summarize(text, max_length, min_length)
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
return summary
|
101 |
except Exception as e:
|
102 |
logger.error(f"Error during summarization: {str(e)}")
|
103 |
+
# Fall back to simple summarization on error
|
104 |
+
return simple_summarize(text, max_length, min_length)
|
|
|
|
|
|
|
|
|
105 |
|
106 |
# Create Gradio interface
|
107 |
+
demo = gr.Interface(
|
108 |
+
fn=summarize_text,
|
109 |
+
inputs=[
|
110 |
+
gr.Textbox(
|
111 |
+
lines=10,
|
112 |
+
label="Text to Summarize",
|
113 |
+
placeholder="Enter text to summarize (at least 50 characters)"
|
114 |
+
),
|
115 |
+
gr.Slider(50, 500, value=150, label="Max Length"),
|
116 |
+
gr.Slider(10, 200, value=30, label="Min Length")
|
117 |
+
],
|
118 |
+
outputs=gr.Textbox(label="Summary"),
|
119 |
+
title="StudAI Text Summarization",
|
120 |
+
description="This service provides text summarization for the StudAI Android app.",
|
121 |
+
examples=[
|
122 |
+
["The coronavirus pandemic has led to a surge in remote work. Companies around the world have had to adapt to new ways of working, with many employees setting up home offices. This shift has led to changes in productivity, work-life balance, and communication patterns. Some studies suggest that remote work can increase productivity, while others point to challenges in collaboration and team cohesion. Organizations are now considering hybrid models for the future of work.", 150, 30]
|
123 |
+
],
|
124 |
+
allow_flagging="never"
|
125 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
+
# Launch with parameters optimized for Spaces
|
128 |
+
demo.launch(share=False, server_name="0.0.0.0", server_port=7860)
|
requirements.txt
CHANGED
@@ -2,5 +2,5 @@ gradio==4.13.0
|
|
2 |
transformers==4.35.2
|
3 |
torch==2.0.1
|
4 |
numpy<2.0.0
|
5 |
-
|
6 |
-
|
|
|
2 |
transformers==4.35.2
|
3 |
torch==2.0.1
|
4 |
numpy<2.0.0
|
5 |
+
requests==2.31.0
|
6 |
+
accelerate==0.25.0
|