Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from transformers import pipeline | |
| # 1. Thread Optimization & GPU/CPU Configuration | |
| # Force PyTorch to use 1 thread for CPU inference to avoid excessive context switching in constrained envs | |
| import torch | |
| torch.set_num_threads(1) | |
| # Global lazy-loaded pipelines to minimize startup latency | |
| _sentiment_pipeline = None | |
| _zero_shot_pipeline = None | |
| def get_sentiment_pipeline(): | |
| global _sentiment_pipeline | |
| if _sentiment_pipeline is None: | |
| # Using distilbert-base-uncased-finetuned-sst-2-english | |
| # Extremely fast, highly accurate (~92% on SST-2), and highly efficient for production CPUs | |
| _sentiment_pipeline = pipeline( | |
| "sentiment-analysis", | |
| model="distilbert-base-uncased-finetuned-sst-2-english", | |
| revision="714eb0f" | |
| ) | |
| return _sentiment_pipeline | |
| def get_zero_shot_pipeline(): | |
| global _zero_shot_pipeline | |
| if _zero_shot_pipeline is None: | |
| # Using typeform/distilbert-base-uncased-mnli | |
| # Extremely lightweight (~268MB), offering BART-like zero-shot capability at a fraction of the memory footprint | |
| _zero_shot_pipeline = pipeline( | |
| "zero-shot-classification", | |
| model="typeform/distilbert-base-uncased-mnli" | |
| ) | |
| return _zero_shot_pipeline | |
| # 2. Main Logic Handlers | |
| def analyze_sentiment(text): | |
| if not text or not text.strip(): | |
| return {"Error": 1.0}, "Please enter valid text." | |
| try: | |
| classifier = get_sentiment_pipeline() | |
| results = classifier(text) | |
| # Format the output beautifully for Gradio's gr.Label | |
| # e.g., {"POSITIVE": 0.999, "NEGATIVE": 0.001} | |
| label = results[0]['label'] | |
| score = results[0]['score'] | |
| other_label = "NEGATIVE" if label == "POSITIVE" else "POSITIVE" | |
| output_data = { | |
| label: score, | |
| other_label: 1.0 - score | |
| } | |
| emoji = "✨" if label == "POSITIVE" else "⚠️" | |
| explanation = f"The model is **{score:.2%}** confident that this text has a **{label.lower()}** sentiment {emoji}." | |
| return output_data, explanation | |
| except Exception as e: | |
| return {"Error": 1.0}, f"Inference Error: {str(e)}" | |
| def classify_zero_shot(text, candidate_labels): | |
| if not text or not text.strip(): | |
| return {"Error": 1.0}, "Please enter valid text." | |
| if not candidate_labels or not candidate_labels.strip(): | |
| return {"Error": 1.0}, "Please enter at least one candidate label." | |
| try: | |
| # Clean and split the candidate labels | |
| labels_list = [label.strip() for label in candidate_labels.split(",") if label.strip()] | |
| if len(labels_list) == 0: | |
| return {"Error": 1.0}, "Please provide valid comma-separated labels." | |
| classifier = get_zero_shot_pipeline() | |
| results = classifier(text, candidate_labels=labels_list) | |
| # Gradio Label component expects a dict of {label_name: float_probability} | |
| output_data = {label: score for label, score in zip(results['labels'], results['scores'])} | |
| top_label = results['labels'][0] | |
| top_score = results['scores'][0] | |
| explanation = f"**Top Match**: classified as **'{top_label}'** with **{top_score:.1%}** confidence." | |
| return output_data, explanation | |
| except Exception as e: | |
| return {"Error": 1.0}, f"Inference Error: {str(e)}" | |
| # 3. Custom Theming & Premium Visual Layout | |
| # Sleek, enterprise-grade Slate and Sapphire design with clean edges | |
| theme = gr.themes.Soft( | |
| primary_hue="indigo", | |
| secondary_hue="blue", | |
| neutral_hue="slate", | |
| font=[gr.themes.GoogleFont("Inter"), "Helvetica Neue", "Arial", "sans-serif"] | |
| ).set( | |
| body_background_fill="*neutral_50", | |
| body_background_fill_dark="*neutral_950", | |
| button_primary_background_fill="linear-gradient(135deg, #4f46e5 0%, #3b82f6 100%)", | |
| button_primary_background_fill_hover="linear-gradient(135deg, #4338ca 0%, #2563eb 100%)", | |
| button_primary_text_color="white", | |
| block_title_text_weight="600", | |
| block_border_width="1px", | |
| block_shadow="rgba(0, 0, 0, 0.05) 0px 4px 12px" | |
| ) | |
| # Custom CSS for glassmorphism headers and beautiful margins | |
| custom_css = """ | |
| .header-container { | |
| background: linear-gradient(135deg, #1e1b4b 0%, #0f172a 100%); | |
| padding: 2.5rem; | |
| border-radius: 12px; | |
| margin-bottom: 2rem; | |
| color: white; | |
| box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.15); | |
| } | |
| .header-title { | |
| font-size: 2.5rem; | |
| font-weight: 800; | |
| letter-spacing: -0.025em; | |
| margin: 0; | |
| background: linear-gradient(to right, #a5b4fc, #818cf8, #60a5fa); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| .header-subtitle { | |
| font-size: 1.1rem; | |
| opacity: 0.85; | |
| margin-top: 0.5rem; | |
| } | |
| .footer-text { | |
| text-align: center; | |
| font-size: 0.85rem; | |
| color: #64748b; | |
| margin-top: 3rem; | |
| } | |
| """ | |
| with gr.Blocks(title="NexusCorp AI Suite") as demo: | |
| # 4. Premium Header Section | |
| gr.HTML( | |
| """ | |
| <div class="header-container"> | |
| <h1 class="header-title">NexusCorp NLP Engine</h1> | |
| <p class="header-subtitle">State-of-the-art NLP classification models optimized for instant pipeline inference</p> | |
| </div> | |
| """ | |
| ) | |
| with gr.Tabs(): | |
| # Tab 1: Sentiment Analysis | |
| with gr.Tab("Sentiment Intelligence"): | |
| gr.Markdown( | |
| """ | |
| ### 🎭 Real-Time Sentiment & Polarity Analysis | |
| Detect emotional valence (Positive or Negative) in conversational copy, client feedback, or support tickets. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=5): | |
| sentiment_input = gr.Textbox( | |
| label="Analyze Copy", | |
| placeholder="Type or paste your text here (e.g., 'The new service launch was absolutely stellar, we got incredible feedback!')...", | |
| lines=5, | |
| max_lines=12 | |
| ) | |
| # Examples for users to interact with immediately | |
| gr.Examples( | |
| examples=[ | |
| ["The new update is absolute perfection! Visual design looks stunning and responsiveness is stellar."], | |
| ["I'm extremely disappointed with the delayed shipment, and the customer support was non-responsive."], | |
| ["The product works fine, although it has a few minor bugs that need to be patched in the next release."] | |
| ], | |
| inputs=sentiment_input, | |
| label="Pre-loaded Enterprise Scenarios" | |
| ) | |
| sentiment_btn = gr.Button("Execute Analysis", variant="primary") | |
| with gr.Column(scale=4): | |
| sentiment_label = gr.Label( | |
| label="Sentiment Distribution", | |
| num_top_classes=2 | |
| ) | |
| sentiment_explanation = gr.Markdown("*Awaiting analysis request...*") | |
| sentiment_btn.click( | |
| fn=analyze_sentiment, | |
| inputs=sentiment_input, | |
| outputs=[sentiment_label, sentiment_explanation] | |
| ) | |
| # Tab 2: Zero-Shot Classification | |
| with gr.Tab("Zero-Shot Classification"): | |
| gr.Markdown( | |
| """ | |
| ### 🏷️ Zero-Shot Dynamic Categorizer | |
| Classify any piece of copy into **custom labels** on the fly without any model re-training. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=5): | |
| zero_shot_text = gr.Textbox( | |
| label="Input Text", | |
| placeholder="Type text to classify here...", | |
| lines=4 | |
| ) | |
| zero_shot_labels = gr.Textbox( | |
| label="Candidate Labels (Comma-Separated)", | |
| placeholder="e.g. Finance, Technology, Health, Sports, Customer Support", | |
| value="Finance, Technology, Support, Marketing" | |
| ) | |
| gr.Examples( | |
| examples=[ | |
| [ | |
| "We need to schedule a software patch rollout tonight to resolve the high CPU consumption on the database server.", | |
| "Technology, Infrastructure, Finance, Urgent Operations" | |
| ], | |
| [ | |
| "Our marketing campaign saw a 25% lift in click-through rates after changing the call-to-action button color.", | |
| "Creative Design, Marketing Metrics, Legal, Engineering" | |
| ], | |
| [ | |
| "Can I get a refund for my order? The invoice was generated with double the tax rate.", | |
| "Billing Support, Bug Report, Sales Inquiries, Careers" | |
| ] | |
| ], | |
| inputs=[zero_shot_text, zero_shot_labels], | |
| label="Zero-Shot Use Cases" | |
| ) | |
| zero_shot_btn = gr.Button("Categorize Copy", variant="primary") | |
| with gr.Column(scale=4): | |
| zero_shot_label = gr.Label( | |
| label="Probability Distribution" | |
| ) | |
| zero_shot_explanation = gr.Markdown("*Awaiting categorization request...*") | |
| zero_shot_btn.click( | |
| fn=classify_zero_shot, | |
| inputs=[zero_shot_text, zero_shot_labels], | |
| outputs=[zero_shot_label, zero_shot_explanation] | |
| ) | |
| # Premium footer info | |
| gr.HTML( | |
| """ | |
| <div class="footer-text"> | |
| <p>NexusCorp NLP Suite v1.2.0 • Powered by Hugging Face Transformers & Gradio</p> | |
| <p style="font-size: 0.75rem; margin-top: 0.25rem; opacity: 0.8;">Configured for rapid containerized deployment</p> | |
| </div> | |
| """ | |
| ) | |
| # 5. Local Running and Deployment Configuration | |
| if __name__ == "__main__": | |
| # Get port from environment variable (required for Hugging Face Spaces and other cloud runtimes) | |
| port = int(os.environ.get("PORT", 7860)) | |
| # Launch Gradio interface. | |
| # server_name="0.0.0.0" is critical for Docker/cloud environments to allow external requests | |
| demo.queue().launch( | |
| server_name="0.0.0.0", | |
| server_port=port, | |
| share=False, | |
| theme=theme, | |
| css=custom_css | |
| ) | |