Spaces:
Running on Zero
Running on Zero
| import gradio as gr | |
| import spaces | |
| from transformers import pipeline | |
| # Available models shown in the dropdown. | |
| MODEL_OPTIONS = { | |
| "XLM-RoBERTa X-Stance": "MatteoFasulo/xlm-roberta-xstance", | |
| "mDeBERTa-v3 X-Stance": "MatteoFasulo/mdeberta-v3-xstance", | |
| } | |
| # Cache one classifier for each model so it is not reloaded on every request. | |
| classifiers = {} | |
| def get_classifier(model_name): | |
| if model_name not in classifiers: | |
| classifiers[model_name] = pipeline( | |
| task="text-classification", | |
| model=model_name, | |
| device=0, | |
| ) | |
| return classifiers[model_name] | |
| def predict_stance(selected_model, question, comment): | |
| if not question.strip() or not comment.strip(): | |
| return "⚠️ Please provide both a question and a comment.", None | |
| try: | |
| model_name = MODEL_OPTIONS[selected_model] | |
| model = get_classifier(model_name) | |
| result = model( | |
| { | |
| "text": question, | |
| "text_pair": comment, | |
| } | |
| ) | |
| if isinstance(result, list) and len(result) > 0: | |
| prediction = result[0] | |
| label = prediction["label"] | |
| score = prediction["score"] | |
| elif isinstance(result, dict): | |
| label = result.get("label", "Unknown") | |
| score = result.get("score", 0.0) | |
| else: | |
| return "⚠️ Unexpected model output format.", None | |
| normalized_label = label.upper() | |
| if "FAVOR" in normalized_label: | |
| emoji = "✅" | |
| color = "green" | |
| explanation = "The comment **supports** the political question." | |
| elif "AGAINST" in normalized_label: | |
| emoji = "❌" | |
| color = "red" | |
| explanation = "The comment **opposes** the political question." | |
| else: | |
| emoji = "❓" | |
| color = "orange" | |
| explanation = "The model returned an unrecognized stance label." | |
| output = f""" | |
| ### {emoji} Prediction: **{label}** | |
| <div style=" | |
| padding: 10px; | |
| border-left: 4px solid {color}; | |
| background-color: #f5f5f5; | |
| margin: 10px 0; | |
| "> | |
| {explanation} | |
| </div> | |
| **Confidence:** {score:.2%} | |
| **Model:** `{model_name}` | |
| --- | |
| *💡 Tip: Try questions in German or French!* | |
| """ | |
| if "FAVOR" in normalized_label: | |
| confidence_dist = { | |
| "FAVOR": score, | |
| "AGAINST": 1 - score, | |
| } | |
| elif "AGAINST" in normalized_label: | |
| confidence_dist = { | |
| "AGAINST": score, | |
| "FAVOR": 1 - score, | |
| } | |
| else: | |
| confidence_dist = {label: score} | |
| return output, confidence_dist | |
| except Exception as e: | |
| error_msg = f"❌ Error during prediction: {str(e)}" | |
| return error_msg, None | |
| with gr.Blocks( | |
| title="Multilingual Stance Detection", | |
| theme=gr.themes.Soft(), | |
| ) as demo: | |
| gr.Markdown(""" | |
| # 🌍 Multilingual Political Stance Detection | |
| Select a model and predict whether a comment **supports (FAVOR)** | |
| or **opposes (AGAINST)** a political question. | |
| The models support multilingual stance detection, including | |
| 🇩🇪 German and 🇫🇷 French. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| model_dropdown = gr.Dropdown( | |
| choices=list(MODEL_OPTIONS.keys()), | |
| value="XLM-RoBERTa X-Stance", | |
| label="🤖 Model", | |
| info="Choose the model used for stance classification.", | |
| interactive=True, | |
| ) | |
| question_input = gr.Textbox( | |
| label="🗳️ Political Question", | |
| lines=3, | |
| placeholder=( | |
| "e.g. Sollte die Schweiz die Kernenergie verbieten?" | |
| ), | |
| ) | |
| comment_input = gr.Textbox( | |
| label="💬 Comment", | |
| lines=5, | |
| placeholder=( | |
| "e.g. Erneuerbare Energien sollten Kernenergie " | |
| "ersetzen, weil sie sicherer und nachhaltiger sind." | |
| ), | |
| ) | |
| submit_btn = gr.Button( | |
| "🔍 Analyze Stance", | |
| variant="primary", | |
| ) | |
| with gr.Column(): | |
| output_text = gr.Markdown( | |
| label="Analysis Results", | |
| ) | |
| confidence_plot = gr.Label( | |
| label="Confidence Distribution", | |
| num_top_classes=2, | |
| ) | |
| gr.Examples( | |
| examples=[ | |
| [ | |
| "Sollte die Schweiz erneuerbare Energien stärker fördern?", | |
| ( | |
| "Investitionen in erneuerbare Energien reduzieren " | |
| "Emissionen und verbessern die Energieunabhängigkeit." | |
| ), | |
| ], | |
| [ | |
| "Sollte die Schweiz der Europäischen Union beitreten?", | |
| ( | |
| "Die Schweiz muss ihre Unabhängigkeit und Neutralität " | |
| "um jeden Preis bewahren." | |
| ), | |
| ], | |
| [ | |
| "Sollte die Schweiz die Kernenergie schrittweise abschaffen?", | |
| ( | |
| "Kernenergie ist gefährlich und sollte durch sicherere " | |
| "Alternativen ersetzt werden." | |
| ), | |
| ], | |
| [ | |
| "Sollte die Schweiz die Einwanderung begrenzen?", | |
| ( | |
| "Eine Begrenzung der Einwanderung schadet der Wirtschaft " | |
| "und dem kulturellen Austausch." | |
| ), | |
| ], | |
| [ | |
| ( | |
| "Sollte die Schweiz ein bedingungsloses " | |
| "Grundeinkommen einführen?" | |
| ), | |
| ( | |
| "Ein bedingungsloses Grundeinkommen würde die soziale " | |
| "Sicherheit stärken und Armut reduzieren." | |
| ), | |
| ], | |
| [ | |
| ( | |
| "La Suisse devrait-elle promouvoir davantage " | |
| "les énergies renouvelables?" | |
| ), | |
| ( | |
| "Les investissements dans les énergies renouvelables " | |
| "réduisent les émissions et améliorent " | |
| "l'indépendance énergétique." | |
| ), | |
| ], | |
| [ | |
| "La Suisse devrait-elle adhérer à l'Union européenne?", | |
| ( | |
| "La Suisse doit préserver son indépendance et sa " | |
| "neutralité à tout prix." | |
| ), | |
| ], | |
| [ | |
| ( | |
| "La Suisse devrait-elle éliminer progressivement " | |
| "l'énergie nucléaire?" | |
| ), | |
| ( | |
| "L'énergie nucléaire est dangereuse et devrait être " | |
| "remplacée par des alternatives plus sûres." | |
| ), | |
| ], | |
| [ | |
| "La Suisse devrait-elle limiter l'immigration?", | |
| ( | |
| "La limitation de l'immigration nuit à l'économie " | |
| "et aux échanges culturels." | |
| ), | |
| ], | |
| [ | |
| ( | |
| "La Suisse devrait-elle introduire un revenu " | |
| "de base inconditionnel?" | |
| ), | |
| ( | |
| "Un revenu de base inconditionnel renforcerait la " | |
| "sécurité sociale et réduirait la pauvreté." | |
| ), | |
| ], | |
| ], | |
| inputs=[question_input, comment_input], | |
| label="📝 Try these examples", | |
| ) | |
| prediction_inputs = [ | |
| model_dropdown, | |
| question_input, | |
| comment_input, | |
| ] | |
| prediction_outputs = [ | |
| output_text, | |
| confidence_plot, | |
| ] | |
| submit_btn.click( | |
| fn=predict_stance, | |
| inputs=prediction_inputs, | |
| outputs=prediction_outputs, | |
| ) | |
| comment_input.submit( | |
| fn=predict_stance, | |
| inputs=prediction_inputs, | |
| outputs=prediction_outputs, | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |