import gradio as gr from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch from theme import custom_css, header # -------------------------- # Model setup # -------------------------- MODEL_ID = "roncc13/autotrain-ixzm9-t6dbc" tokenizer = AutoTokenizer.from_pretrained(MODEL_ID) model = AutoModelForSequenceClassification.from_pretrained(MODEL_ID) label_names = ["fake", "real"] def classify(text: str): if not text.strip(): return {"fake": 0.0, "real": 0.0} inputs = tokenizer( text, return_tensors="pt", truncation=True, padding=True, max_length=256, ) with torch.no_grad(): outputs = model(**inputs) probs = torch.softmax(outputs.logits, dim=-1)[0].tolist() return {label_names[i]: float(probs[i]) for i in range(len(label_names))} # -------------------------- # Helpers for rendering result HTML # -------------------------- def _result_label_html(label: str, css_class: str) -> str: return f'{label}' def _confidence_text_html(conf_pct: int) -> str: return ( "
" f"{conf_pct}%" "confidence" "
" ) def _confidence_bar_html(conf_pct: int) -> str: return ( "
" f"
" "
" ) # Initial (empty) state values for the result card INITIAL_LABEL_HTML = _result_label_html("—", "badge-pill badge-neutral") INITIAL_CONF_HTML = _confidence_text_html(0) INITIAL_BAR_HTML = _confidence_bar_html(0) # -------------------------- # UI with Tabs # -------------------------- with gr.Blocks(fill_height=True) as demo: gr.HTML("
") # ===== Analyzer tab ===== with gr.Tab("Analyzer"): header() gr.HTML( """
Check Cebuano text for a misleading writing style.
This tool analyzes linguistic patterns and writing style in Cebuano text to detect potential misinformation. It does not verify factual correctness. The model returns a classification (Fake/Legit) and a confidence score based on writing patterns.
""" ) with gr.Row(elem_classes=["two-col"], equal_height=True): # Left: input card with gr.Column(scale=3): with gr.Group(elem_classes=["glass-card"], elem_id="input-card"): gr.Markdown( "#### Text input\n" "Cebuano only. This tool checks linguistic patterns; it does not verify facts." ) gr.Markdown( "> **Example** \n" "> \u201cNakadisubre og milagro nga tambal sa COVID\u201119 ang usa ka local doktor, " "giingon nga walay side effects ug dili kinahanglan og bakuna.\u201d" ) news_text = gr.Textbox( lines=7, label="", placeholder="Paste Cebuano news text here...", elem_id="news-textbox", ) with gr.Row(elem_classes=["btn-row"]): analyze_btn = gr.Button("Analyze", elem_classes=["btn-primary-custom"]) clear_btn = gr.Button("Clear", elem_classes=["btn-secondary-custom"]) gr.Markdown( "" "Tip: Keep inputs under 1,000 characters for faster results." "", container=False, ) # Right: result card with gr.Column(scale=2): with gr.Group(elem_classes=["glass-card"], elem_id="result-card"): gr.Markdown("#### Result") result_label_html = gr.HTML(INITIAL_LABEL_HTML) conf_text = gr.HTML(INITIAL_CONF_HTML) conf_bar = gr.HTML(INITIAL_BAR_HTML) gr.Markdown( "" "Model: CMD\u2011BERT (fine\u2011tuned BERT\u2011base). " "Output: Label and confidence score for the submitted text." "", container=False, ) def analyze_ui(text): if not text or not text.strip(): return INITIAL_LABEL_HTML, INITIAL_CONF_HTML, INITIAL_BAR_HTML probs = classify(text) fake_p = probs.get("fake", 0.0) real_p = probs.get("real", 0.0) if fake_p >= real_p: label, css_class, conf = "FAKE", "badge-pill badge-fake", fake_p else: label, css_class, conf = "LEGIT", "badge-pill badge-real", real_p # Clamp and convert to integer percentage 0–100 conf_pct = max(0, min(100, int(round(conf * 100)))) return ( _result_label_html(label, css_class), _confidence_text_html(conf_pct), _confidence_bar_html(conf_pct), ) def clear_ui(): return "", INITIAL_LABEL_HTML, INITIAL_CONF_HTML, INITIAL_BAR_HTML analyze_btn.click( fn=analyze_ui, inputs=news_text, outputs=[result_label_html, conf_text, conf_bar], ) clear_btn.click( fn=clear_ui, inputs=None, outputs=[news_text, result_label_html, conf_text, conf_bar], ) # ===== How it works tab ===== with gr.Tab("How it works"): header() with gr.Group(elem_classes=["glass-card"], elem_id="hiw-intro-card"): gr.Markdown( "## How CMD\u2011BERT works\n" "CMD\u2011BERT is an AI\u2011augmented linguistic model that focuses on writing style, " "not literal truth. It looks for patterns such as exaggerated wording, " "over\u2011confident claims, and framing that often appear in misleading content." ) with gr.Row(elem_classes=["card-row"]): with gr.Column(): with gr.Group(elem_classes=["glass-card"], elem_id="hiw-step1-card"): gr.Markdown( "### 1. Input and preprocessing\n" "- User pastes a Cebuano headline, post, or short article.\n" "- The text is tokenized and trimmed to a safe maximum length.\n" "- Inputs are processed in memory and not stored permanently." ) with gr.Column(): with gr.Group(elem_classes=["glass-card"], elem_id="hiw-step2-card"): gr.Markdown( "### 2. CMD\u2011BERT analysis\n" "- CMD\u2011BERT is a fine\u2011tuned BERT\u2011base model trained on Cebuano news.\n" "- It computes probabilities for two classes: **Fake** and **Legit**.\n" "- The highest\u2011probability class becomes the predicted label." ) with gr.Group(elem_classes=["glass-card"], elem_id="hiw-step3-card"): gr.Markdown( "### 3. Result and interpretation\n" "- The interface shows the predicted label and confidence bar.\n" "- Users are reminded that this is a screening tool only.\n" "- Final judgment should always involve human critical thinking." ) # ===== About tab ===== with gr.Tab("About"): header() with gr.Group(elem_classes=["glass-card"], elem_id="about-intro-card"): gr.Markdown( "## About CMD\u2011BERT\n" "**CMD\u2011BERT: An AI Augmented Linguistic Recognition Model for Cebuano Fake News Detection**\n\n" "CMD\u2011BERT is a thesis project in the Department of Computer Engineering at " "Cebu Technological University\u2013Main Campus. The tool aims to support Cebuano readers " "by highlighting potentially misleading writing patterns in online news and posts." ) with gr.Group(elem_classes=["glass-card"], elem_id="about-thesis-card"): gr.Markdown( "### Thesis information\n" "_A Thesis Project presented to the Faculty of the Department of Computer Engineering_\n\n" "Cebu Technological University\u2013Main Campus \n" "Cebu City, Philippines \n\n" "_In partial fulfillment of the requirements for the degree_ \n" "**Bachelor of Science in Computer Engineering**\n\n" "**By:** \n" "- Cabag, Ronilo Jose Jr. S. \n" "- Libron, Andio Mart \n" "- Omega, Noel \n\n" "**Adviser:** Engr. Jueco, M.Eng. \n" "January 2026" ) # ===== Feedback tab ===== with gr.Tab("Feedback"): header() with gr.Group(elem_classes=["glass-card"], elem_id="fb-intro-card"): gr.Markdown( "## Feedback and model improvement\n" "CMD\u2011BERT is experimental and continuously improving. Your feedback can help " "identify model mistakes, usability issues, and opportunities to refine the dataset." ) with gr.Row(elem_classes=["card-row"]): with gr.Column(): with gr.Group(elem_classes=["glass-card"], elem_id="fb-form-card"): fb_type = gr.Dropdown( ["Bug / technical issue", "Model mistake", "UI suggestion", "Other"], label="Feedback type", ) fb_text = gr.Textbox( lines=6, label="Your message or example text", placeholder="Describe the issue or paste an example of text the model misclassified.", elem_id="fb-textbox", ) fb_email = gr.Textbox( label="Email (optional, for follow\u2011up)", placeholder="you@example.com", elem_id="fb-email-textbox", ) fb_checkbox = gr.Checkbox( label="Allow us to use this text anonymously for future model improvements.", value=True, ) fb_submit = gr.Button("Submit feedback", elem_classes=["btn-primary-custom"]) with gr.Column(): with gr.Group(elem_classes=["glass-card"], elem_id="fb-faq-card"): fb_status = gr.Markdown("No feedback submitted yet.") gr.Markdown( "### FAQ\n" "**What happens to my feedback?** \n" "It is stored securely and reviewed by the CMD\u2011BERT thesis team.\n\n" "**Will CMD\u2011BERT replace human fact\u2011checkers?** \n" "No. It is a support tool to encourage critical reading.\n\n" "**Who maintains this tool?** \n" "The CMD\u2011BERT thesis team at Cebu Technological University\u2013Main Campus." ) def save_feedback(ftype, text, email, consent): if not text.strip(): return "Please enter a message before submitting." return "Thank you for your feedback! It has been recorded." fb_submit.click( fn=save_feedback, inputs=[fb_type, fb_text, fb_email, fb_checkbox], outputs=fb_status, ) if __name__ == "__main__": demo.launch(css=custom_css, theme=gr.themes.Soft())