Spaces:
Sleeping
Sleeping
| """ | |
| Taana-Tracker v1.0 β (Hindi + English) Sarcasm Detector | |
| Model: XLM-RoBERTa (fine-tuned) | Framework: PyTorch | UI: Streamlit | |
| """ | |
| import streamlit as st | |
| import torch | |
| import pandas as pd | |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| from pathlib import Path | |
| # βββββββββββββββββββββββ PAGE CONFIG βββββββββββββββββββββββββββββββββββββββββ | |
| st.set_page_config( | |
| page_title="Taana-Tracker: AI Sarcasm Intelligence", | |
| page_icon="π₯", | |
| layout="wide", | |
| initial_sidebar_state="collapsed", | |
| ) | |
| # βββββββββββββββββββββββ CSS ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| st.markdown(""" | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); | |
| html, body, [class*="css"] { font-family: 'Inter', sans-serif; } | |
| .hero { | |
| background: linear-gradient(135deg, #0f0c29, #302b63, #24243e); | |
| border-radius: 16px; | |
| padding: 36px 28px 28px; | |
| text-align: center; | |
| margin-bottom: 24px; | |
| border: 1px solid rgba(255,255,255,0.07); | |
| } | |
| .hero h1 { font-size: 2.6rem; margin: 0; color: #fff; letter-spacing: -1px; } | |
| .hero p { color: #aaa; font-size: 1rem; margin-top: 8px; } | |
| .badge { | |
| display: inline-block; | |
| background: rgba(255,255,255,0.1); | |
| color: #e0e0e0; | |
| border-radius: 30px; | |
| padding: 4px 14px; | |
| font-size: 0.78rem; | |
| margin: 6px 3px 0; | |
| border: 1px solid rgba(255,255,255,0.12); | |
| } | |
| .verdict-sarcastic { | |
| background: linear-gradient(135deg, #800020, #4a0010); | |
| color: #f7f7fb; border-radius: 14px; | |
| padding: 24px; text-align: center; margin: 14px 0; | |
| } | |
| .verdict-neutral { | |
| background: linear-gradient(135deg, #2ecc71, #16a085); | |
| color: #f4fffa; border-radius: 14px; | |
| padding: 24px; text-align: center; margin: 14px 0; | |
| } | |
| .verdict-title { font-size: 1.8rem; font-weight: 700; margin-bottom: 4px; } | |
| .verdict-sub { font-size: 0.95rem; opacity: 0.9; } | |
| .warn-box { | |
| background: rgba(255,193,7,0.12); | |
| border-left: 4px solid #FFC107; | |
| border-radius: 8px; padding: 12px 16px; margin: 12px 0; | |
| color: #ffd54f; font-size: 0.9rem; | |
| } | |
| .info-box { | |
| background: rgba(0,188,212,0.1); | |
| border-left: 4px solid #00BCD4; | |
| border-radius: 8px; padding: 12px 16px; margin: 12px 0; | |
| color: #80deea; font-size: 0.9rem; | |
| } | |
| .stress-row { | |
| background: rgba(255,255,255,0.03); | |
| border-radius: 10px; padding: 14px 16px; margin: 8px 0; | |
| border: 1px solid rgba(255,255,255,0.07); | |
| font-size: 0.92rem; | |
| } | |
| .prob-bar-wrap { margin: 10px 0; } | |
| .prob-label { font-size: 0.85rem; color: #aaa; margin-bottom: 4px; } | |
| [data-testid="metric-container"] { | |
| background: rgba(255,255,255,0.04); | |
| border: 1px solid rgba(255,255,255,0.08); | |
| border-radius: 12px; padding: 14px 16px; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # βββββββββββββββββββββββ CONSTANTS βββββββββββββββββββββββββββββββββββββββββββ | |
| FINETUNED_REPO = "PrachiSandipkumar/Taana-Tracker-Sarcasm" | |
| BASE_MODEL = "xlm-roberta-base" | |
| MAX_LEN = 256 | |
| DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| # βββββββββββββββββββββββ MODEL LOADING βββββββββββββββββββββββββββββββββββββββ | |
| def load_model(): | |
| """ | |
| Loads tokenizer from xlm-roberta-base and fine-tuned weights | |
| from the dedicated Hugging Face model repository. | |
| """ | |
| load_log = [] | |
| source = "base-NOT-fine-tuned" | |
| # 1. Tokenizer β Always pull from xlm-roberta-base as per Cell 22 | |
| try: | |
| tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL) | |
| load_log.append("Tokenizer: Successfully loaded from xlm-roberta-base") | |
| except Exception as e: | |
| st.error(f"Failed to load base tokenizer: {e}") | |
| raise e | |
| # 2. Model β Pull configuration and weights from your fine-tuned repo | |
| try: | |
| # Load model with weights from your fine-tuned repository | |
| model = AutoModelForSequenceClassification.from_pretrained( | |
| FINETUNED_REPO, | |
| num_labels=2 | |
| ) | |
| # Check and handle vocab size alignment safely | |
| tokenizer_vocab_size = len(tokenizer) | |
| model_vocab_size = model.get_input_embeddings().weight.shape[0] | |
| if tokenizer_vocab_size != model_vocab_size: | |
| load_log.append(f"Resizing embeddings: {model_vocab_size} β {tokenizer_vocab_size}") | |
| model.resize_token_embeddings(tokenizer_vocab_size) | |
| source = "fine-tuned" | |
| load_log.append(f"Model: Fine-tuned weights successfully loaded from HF Hub ({FINETUNED_REPO})") | |
| except Exception as e: | |
| # Fallback safeguard back to base if repo files fail to initialize | |
| load_log.append(f"Model: Fine-tuned load FAILED β {e}") | |
| load_log.append("Model: WARNING β Falling back to base xlm-roberta-base.") | |
| model = AutoModelForSequenceClassification.from_pretrained(BASE_MODEL, num_labels=2) | |
| source = "base-NOT-fine-tuned" | |
| model.to(DEVICE) | |
| model.eval() | |
| return model, tokenizer, source, load_log | |
| # βββββββββββββββββββββββ NOTEBOOK FUNCTIONS ββββββββββββββββββββββββββββββββββ | |
| def clean_text(text: str) -> str: | |
| """From notebook Cell 9.""" | |
| return text.strip() | |
| def predict_sarcasm(text: str, model, tokenizer): | |
| """ | |
| Exact replica of predict_sarcasm() from notebook Cell 42. | |
| Patched for stable single-sentence inference on Hugging Face. | |
| Returns: (predicted_label, confidence, sarcasm_pct, not_sarcasm_pct) | |
| """ | |
| text = clean_text(text) | |
| # FIX: Changed padding to 'max_length' to match your training pipeline shape | |
| inputs = tokenizer( | |
| text, | |
| padding="max_length", | |
| truncation=True, | |
| max_length=MAX_LEN, | |
| return_tensors="pt" | |
| ) | |
| input_ids = inputs["input_ids"].to(DEVICE) | |
| attention_mask = inputs["attention_mask"].to(DEVICE) | |
| model.eval() | |
| with torch.no_grad(): | |
| outputs = model(input_ids=input_ids, attention_mask=attention_mask) | |
| logits = outputs.logits | |
| probabilities = torch.softmax(logits, dim=1) | |
| predicted_class = torch.argmax(probabilities, dim=1).item() | |
| confidence = probabilities[0][predicted_class].item() | |
| label_map = {0: "Not Sarcastic", 1: "Sarcastic"} | |
| predicted_label = label_map[predicted_class] | |
| sarcasm_pct = probabilities[0][1].item() * 100 | |
| not_sarcasm_pct = probabilities[0][0].item() * 100 | |
| return predicted_label, confidence, sarcasm_pct, not_sarcasm_pct | |
| # βββββββββββββββββββββββ HELPERS βββββββββββββββββββββββββββββββββββββββββββββ | |
| def confidence_label(conf: float) -> str: | |
| if conf >= 0.90: return "High Confidence" | |
| if conf >= 0.70: return "Moderate" | |
| return "Low / Uncertain" | |
| def render_result(label, confidence, sarcasm_pct, not_sarcasm_pct): | |
| """Shared result block used in Tab 1 and Tab 2.""" | |
| conf_lbl = confidence_label(confidence) | |
| css_cls = "verdict-sarcastic" if label == "Sarcastic" else "verdict-neutral" | |
| icon = "π" if label == "Sarcastic" else "π" | |
| st.markdown(f""" | |
| <div class='{css_cls}'> | |
| <div class='verdict-title'>{icon} {label}</div> | |
| <div class='verdict-sub'>Confidence: {confidence*100:.1f}% Β· {conf_lbl}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Probability bars (plain HTML β no extra lib needed) | |
| st.markdown(f""" | |
| <div class='prob-bar-wrap'> | |
| <div class='prob-label'>Sarcastic {sarcasm_pct:.1f}%</div> | |
| <div style='background:#333;border-radius:6px;height:12px;width:100%'> | |
| <div style='background:rgba(217,75,102,0.9);height:12px;border-radius:6px; | |
| width:{sarcasm_pct:.1f}%'></div> | |
| </div> | |
| </div> | |
| <div class='prob-bar-wrap'> | |
| <div class='prob-label'>Not Sarcastic {not_sarcasm_pct:.1f}%</div> | |
| <div style='background:#333;border-radius:6px;height:12px;width:100%'> | |
| <div style='background:rgba(46,204,113,0.85);height:12px;border-radius:6px; | |
| width:{not_sarcasm_pct:.1f}%'></div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Model awareness warning (from requirements) | |
| if confidence < 0.90: | |
| st.markdown(""" | |
| <div class='warn-box'> | |
| β οΈ <strong>Model Awareness:</strong> | |
| This prediction may be less reliable for contextual or implicit (Hindi + English) sarcasm. | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # βββββββββββββββββββββββ MAIN ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def main(): | |
| with st.spinner("Loading modelβ¦"): | |
| model, tokenizer, source, load_log = load_model() | |
| if model is None: | |
| st.error("β Model failed to load.") | |
| st.stop() | |
| # ββ Hero ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| st.markdown(f""" | |
| <div class='hero'> | |
| <h1>π₯ Taana-Tracker</h1> | |
| <p>An AI that understands sarcasm β and knows when it fails</p> | |
| <span class='badge'>XLM-RoBERTa</span> | |
| <span class='badge'>PyTorch</span> | |
| <span class='badge'>(Hindi + English)</span> | |
| <span class='badge'>94% Accuracy</span> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Sidebar β model info | |
| with st.sidebar: | |
| st.markdown("## π₯ Taana-Tracker") | |
| st.markdown("---") | |
| if source == "fine-tuned": | |
| st.success("β Fine-tuned model loaded") | |
| else: | |
| st.error("β Base model only β predictions will be wrong!") | |
| with st.expander("π Load Details", expanded=(source != "fine-tuned")): | |
| for line in load_log: | |
| st.caption(line) | |
| if source != "fine-tuned": | |
| st.warning(""" | |
| **Fix:** Your fine-tuned weights were not found. | |
| Add this to your notebook after Cell 45: | |
| ```python | |
| tokenizer.save_pretrained("/content/fine_tuned_roberta_model") | |
| ``` | |
| Then copy the full `fine_tuned_roberta_model/` folder next to `app.py`. | |
| """) | |
| st.markdown(f""" | |
| **Model:** XLM-RoBERTa-base | |
| **Task:** Binary Classification | |
| **Languages:** (Hindi + English) | |
| **Max Length:** {MAX_LEN} tokens | |
| **Test Accuracy:** 94% | |
| """) | |
| st.markdown("---") | |
| st.markdown("#### π Quick Links") | |
| col_g, col_h = st.columns(2) | |
| with col_g: | |
| if st.button("GitHub", use_container_width=True): | |
| st.markdown("[Repository link](https://github.com/10Prachi2006/Sarcasm-Intelligence-System.git)") | |
| with col_h: | |
| if st.button("HuggingFace", use_container_width=True): | |
| st.markdown("[HuggingFace model](https://huggingface.co/xlm-roberta-base)") | |
| st.markdown("") | |
| col_d, col_p = st.columns(2) | |
| with col_d: | |
| if st.button("Dataset", use_container_width=True): | |
| st.markdown("[Dataset file](https://github.com/10Prachi2006/Sarcasm-Intelligence-System.git)") | |
| with col_p: | |
| if st.button("Paper", use_container_width=True): | |
| st.markdown("[XLM-R paper](https://arxiv.org/abs/1911.02116)") | |
| st.caption("Taana-Tracker v1.0 Β· PyTorch + Streamlit") | |
| # ββ Tabs ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| tab1, tab2, tab3, tab4, tab5 = st.tabs([ | |
| "π Analyze", | |
| "β‘ Live Demo", | |
| "π Model Insights", | |
| "π§ͺ Stress Test", | |
| "π About", | |
| ]) | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TAB 1 β ANALYZE | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with tab1: | |
| st.markdown("### Drop your sentenceβ¦ let's measure the taana level πΆοΈ") | |
| user_text = st.text_area( | |
| label="", | |
| placeholder='e.g. "Wah beta fail hoke bhi proud moment"', | |
| height=120, | |
| max_chars=256, | |
| key="tab1_input", | |
| ) | |
| char_count = len(user_text) | |
| st.caption(f"{char_count}/256 characters") | |
| if st.button("π― Detect Sarcasm", type="primary", use_container_width=True, key="tab1_btn"): | |
| if not user_text.strip(): | |
| st.warning("Please enter some text first.") | |
| else: | |
| with st.spinner("Analyzingβ¦"): | |
| label, confidence, sarcasm_pct, not_sarcasm_pct = predict_sarcasm( | |
| user_text, model, tokenizer | |
| ) | |
| render_result(label, confidence, sarcasm_pct, not_sarcasm_pct) | |
| # Deterministic, no-model reasoning (only for exact matches) | |
| reasoning_examples = { | |
| "Wah beta fail hoke bhi proud moment": "Possible cue: Contradiction between failure ('fail hoke') and celebration ('proud moment'), a common sarcasm pattern.", | |
| "Bahut badiya, sab barbaad kar diya": "Possible cue: Positive praise followed by negative outcome ('barbaad kar diya').", | |
| "Oh, you're leaving at 6 PM? Half-day le liya kya aaj": "Possible cue: Rhetorical question used to mock normal workplace behavior.", | |
| "Aaj mausam bahut accha hai.": "Possible cue: Straightforward statement without strong sarcasm indicators.", | |
| "Thank you for your support!": "Possible cue: Direct appreciation with no obvious sarcastic indicators.", | |
| } | |
| if user_text in reasoning_examples: | |
| st.info(f"π‘ {reasoning_examples[user_text]}") | |
| c1, c2, c3 = st.columns(3) | |
| with c1: st.metric("π― Verdict", label) | |
| with c2: st.metric("π§ Confidence", f"{confidence*100:.1f}%") | |
| with c3: st.metric("π Conf. Level", confidence_label(confidence)) | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TAB 2 β LIVE DEMO | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with tab2: | |
| st.markdown("### β‘ Live Demo β Click any example to analyze") | |
| demo_examples = { | |
| "πΌ Workplace Sarcasm": [ | |
| "Oh you came on time today, miracle hai kya?", | |
| "Oh, you're leaving at 6 PM? Half-day le liya kya aaj", | |
| "It's okay, you're only 2 hours late, no wories....", | |
| ], | |
| "π€ Tech Sarcasm": [ | |
| "Bhai tera ML model itna fast hai ki output agle janam mein aayega!", | |
| "Wow, you used GenAI for a simple 'Hello World' code? Einstein ho kya", | |
| "Nice logic! Iska patent karwa le, dimaag kharch hone se bach jayega.", | |
| "Bhai kya speed hai... 10 min mein 1 epoch", | |
| "Model itna fast hai, result agle janam mein", | |
| ], | |
| "π Savage Hindi + English": [ | |
| "Wah beta fail hoke bhi proud moment", | |
| "Bahut badiya, sab barbaad kar diya", | |
| "Wah kya baat hai, fail ho gaya", | |
| "Kya baat hai, itni achi salary pe bhi khush nahi ho?", | |
| ], | |
| "π Genuine (Not Sarcastic)": [ | |
| "Aaj mausam bahut accha hai.", | |
| "Mujhe tumhari madad chahiye thi.", | |
| "Thank you for your support!", | |
| "I really appreciate your help.", | |
| ], | |
| } | |
| selected_cat = st.selectbox("Pick a category:", list(demo_examples.keys())) | |
| for idx, ex in enumerate(demo_examples[selected_cat]): | |
| if st.button(f"π {ex}", key=f"demo_{selected_cat}_{idx}", use_container_width=True): | |
| with st.spinner("Analyzingβ¦"): | |
| label, confidence, sarcasm_pct, not_sarcasm_pct = predict_sarcasm( | |
| ex, model, tokenizer | |
| ) | |
| st.markdown(f"**Analyzing:** `{ex}`") | |
| render_result(label, confidence, sarcasm_pct, not_sarcasm_pct) | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TAB 3 β MODEL INSIGHTS | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with tab3: | |
| st.markdown("### π Model Insights & Performance") | |
| # Metrics from notebook classification_report (Cell 37) | |
| m1, m2, m3, m4 = st.columns(4) | |
| with m1: st.metric("β Accuracy", "94%") | |
| with m2: st.metric("π― Precision", "94%") | |
| with m3: st.metric("π‘ Recall", "94%") | |
| with m4: st.metric("βοΈ F1-Score", "0.94") | |
| st.divider() | |
| # Per-class table from notebook classification_report | |
| st.markdown("#### Per-Class Performance (Test Set β 1,439 samples)") | |
| st.dataframe(pd.DataFrame({ | |
| "Class": ["Not Sarcastic (0)", "Sarcastic (1)"], | |
| "Precision": [0.96, 0.93], | |
| "Recall": [0.91, 0.97], | |
| "F1-Score": [0.93, 0.95], | |
| "Support": [633, 806], | |
| }), use_container_width=True, hide_index=True) | |
| st.divider() | |
| # Confusion matrix from notebook (Cell 36) | |
| st.markdown("#### Confusion Matrix (Test Set)") | |
| st.markdown(""" | |
| | | Predicted: Not Sarcastic | Predicted: Sarcastic | | |
| |---------------------|:------------------------:|:--------------------:| | |
| | **Actual: Not Sarcastic** | 576 β (TN) | 57 β (FP) | | |
| | **Actual: Sarcastic** | 24 β (FN) | 782 β (TP) | | |
| """) | |
| st.divider() | |
| # Dataset analysis from notebook | |
| st.markdown("#### Dataset Analysis") | |
| col_a, col_b = st.columns(2) | |
| with col_a: | |
| st.markdown("**Class Distribution**") | |
| st.dataframe(pd.DataFrame({ | |
| "Class": ["Sarcastic (1)", "Not Sarcastic (0)", "Total"], | |
| "Samples": [5544, 4049, 9593], | |
| "Share": ["57.8%", "42.2%", "100%"], | |
| }), use_container_width=True, hide_index=True) | |
| with col_b: | |
| st.markdown("**Data Splits (from notebook)**") | |
| st.dataframe(pd.DataFrame({ | |
| "Split": ["Train (70%)", "Validation (15%)", "Test (15%)"], | |
| "Samples": [6714, 1439, 1440], | |
| }), use_container_width=True, hide_index=True) | |
| st.divider() | |
| st.markdown("#### π Key Observations") | |
| st.markdown(""" | |
| <div class='info-box'> | |
| <ul style='margin:0;padding-left:18px'> | |
| <li><strong>Strong on explicit sarcasm:</strong> Emotional tone markers ("wah", "bilkul") β high recall for the Sarcastic class (97%).</li> | |
| <li><strong>Weak on implicit/contextual sarcasm:</strong> Sentences requiring conversational history or cultural context are harder for the model.</li> | |
| <li><strong>Hindi + English advantage:</strong> XLM-RoBERTa's multilingual pre-training gives it an edge over monolingual models on code-switched text.</li> | |
| <li><strong>Slight class imbalance:</strong> Sarcastic class has ~37% more samples β reflected in higher recall for class 1.</li> | |
| </ul> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TAB 4 β STRESS TEST | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with tab4: | |
| st.markdown("### π§ͺ Stress Test β Where the Model Fails") | |
| st.markdown(""" | |
| <div class='warn-box'> | |
| π¬ <strong>Transparency:</strong> A model that hides its failures is a dangerous model. | |
| These are cases from the notebook (Cell 43) marked as <code>#--> FAILED</code>. | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Failure cases from notebook Cell 43 β marked #--> FAILED | |
| failure_cases = [ | |
| { | |
| "text": "Bhai tera ML model itna fast hai ki output agle janam mein aayega!", | |
| "expected": "Sarcastic", | |
| "reason": "Indirect metaphor ('next birth = never'). Model misses the cultural exaggeration.", | |
| }, | |
| { | |
| "text": "Please, thoda aur slow chalao car. Cycle wale bhi humein overtake karke jaa raha hai", | |
| "expected": "Sarcastic", | |
| "reason": "Context-dependent irony β meaning flips only when you know slow car + cycles overtaking = embarrassing.", | |
| }, | |
| { | |
| "text": "Oh, you're leaving at 6 PM? Half-day le liya kya aaj", | |
| "expected": "Sarcastic", | |
| "reason": "Workplace irony needing domain context. Question form lowers model confidence.", | |
| }, | |
| { | |
| "text": "Meri MLOps knowledge aur mera bank balanceβdono hi zero hain", | |
| "expected": "Sarcastic", | |
| "reason": "Self-deprecating humor stated plainly β model may read it as factual.", | |
| }, | |
| ] | |
| if st.button("π§ͺ Run All Failure Cases", type="primary", use_container_width=True): | |
| correct = 0 | |
| for i, case in enumerate(failure_cases, 1): | |
| with st.spinner(f"Running case {i}/{len(failure_cases)}β¦"): | |
| label, confidence, _, _ = predict_sarcasm(case["text"], model, tokenizer) | |
| got_it_right = label == case["expected"] | |
| if got_it_right: | |
| correct += 1 | |
| icon = "β " if got_it_right else "β" | |
| conf_lbl = confidence_label(confidence) | |
| st.markdown(f""" | |
| <div class='stress-row'> | |
| <strong>{icon} Case {i}:</strong> <em>"{case['text']}"</em><br><br> | |
| Expected: <strong>{case['expected']}</strong> | | |
| Got: <strong>{label}</strong> | | |
| Confidence: <strong>{confidence*100:.1f}% ({conf_lbl})</strong><br><br> | |
| <span style='color:#888'>π¬ Why it's hard: {case['reason']}</span> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.divider() | |
| st.metric("Score on Hard Cases", f"{correct}/{len(failure_cases)}") | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TAB 5 β ABOUT | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with tab5: | |
| st.markdown("### π About Taana-Tracker") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown("#### System Description") | |
| st.markdown(""" | |
| **Taana-Tracker** is a fine-tuned XLM-RoBERTa model for sarcasm detection | |
| in (Hindi + English) text. | |
| Trained on ~9,593 real-world Hindi + English samples from social media and news comments. | |
| """) | |
| with col2: | |
| st.markdown("#### Tech Stack") | |
| st.dataframe(pd.DataFrame({ | |
| "Component": ["Model", "Framework", "UI", "Language"], | |
| "Technology": ["XLM-RoBERTa-base (fine-tuned)", | |
| "PyTorch + HuggingFace Transformers", | |
| "Streamlit", "Python 3.10+"], | |
| }), use_container_width=True, hide_index=True) | |
| st.divider() | |
| st.markdown("#### β οΈ Limitations") | |
| st.markdown(""" | |
| <div class='warn-box'> | |
| <ul style='margin:0;padding-left:18px'> | |
| <li><strong>Requires context:</strong> Complex sarcasm needing conversational history will often fail.</li> | |
| <li><strong>Cultural nuance:</strong> Idioms and region-specific humor outside the training set get misclassified.</li> | |
| <li><strong>Hindi + English ambiguity:</strong> Variable transliteration and code-switching create genuine model uncertainty.</li> | |
| <li><strong>Dataset ceiling:</strong> ~9,593 samples. More diverse data would improve generalisation.</li> | |
| </ul> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.divider() | |
| st.markdown("#### π References") | |
| st.markdown(""" | |
| - [XLM-RoBERTa Paper β Conneau et al. 2019](https://arxiv.org/abs/1911.02116) | |
| - [HuggingFace `xlm-roberta-base`](https://huggingface.co/xlm-roberta-base) | |
| - [HuggingFace Transformers Docs](https://huggingface.co/docs/transformers) | |
| """) | |
| if __name__ == "__main__": | |
| main() | |