chatbot / app.py
videopix's picture
Update app.py
236b311 verified
from flask import Flask, request, jsonify, render_template_string
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForCausalLM
import torch
from langdetect import detect
import re
import logging
# Silence Flask dev server logs
logging.getLogger("werkzeug").setLevel(logging.ERROR)
app = Flask(__name__)
# ======================================================
# Grammar correction model (NO Java, CPU only)
# ======================================================
GRAMMAR_MODEL = "vennify/t5-base-grammar-correction"
grammar_tokenizer = AutoTokenizer.from_pretrained(GRAMMAR_MODEL)
grammar_model = AutoModelForSeq2SeqLM.from_pretrained(GRAMMAR_MODEL)
grammar_model.eval()
def grammar_check(text):
if not text.strip():
return text
inputs = grammar_tokenizer(
"grammar: " + text,
return_tensors="pt",
truncation=True
)
with torch.no_grad():
outputs = grammar_model.generate(
**inputs,
max_length=256
)
return grammar_tokenizer.decode(
outputs[0],
skip_special_tokens=True
)
# ======================================================
# Text generation model (CPU)
# ======================================================
CHAT_MODEL = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
chat_tokenizer = AutoTokenizer.from_pretrained(CHAT_MODEL)
chat_model = AutoModelForCausalLM.from_pretrained(
CHAT_MODEL,
dtype=torch.float32
)
chat_model.eval()
def generate_text(prompt):
if not prompt.strip():
return ""
inputs = chat_tokenizer(
prompt,
return_tensors="pt"
)
with torch.no_grad():
output = chat_model.generate(
**inputs,
max_new_tokens=150,
do_sample=True,
temperature=0.7,
top_p=0.9
)
return chat_tokenizer.decode(
output[0],
skip_special_tokens=True
)
# ======================================================
# Helpers
# ======================================================
def detect_language(text):
try:
return detect(text)
except:
return "unknown"
def ai_text_detector(text):
words = text.split()
if len(words) < 30:
return "Not enough text to analyze"
avg_len = sum(len(w) for w in words) / len(words)
repetition = len(set(words)) / len(words)
score = 0
if avg_len > 5.5:
score += 1
if repetition < 0.55:
score += 1
if re.search(
r"\b(in conclusion|overall|moreover|furthermore)\b",
text.lower()
):
score += 1
return "Likely AI-generated" if score >= 2 else "Likely human-written"
# ======================================================
# UI (HTML + CSS + JS)
# ======================================================
HTML_PAGE = """
<!DOCTYPE html>
<html>
<head>
<title>Local AI Text Tool</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f4f6f8;
padding: 20px;
}
.container {
max-width: 900px;
margin: auto;
background: white;
padding: 20px;
border-radius: 6px;
}
textarea {
width: 100%;
height: 120px;
margin-bottom: 10px;
padding: 10px;
font-size: 14px;
}
button {
padding: 10px 16px;
margin-right: 5px;
cursor: pointer;
}
.output {
background: #eee;
padding: 10px;
margin-top: 10px;
white-space: pre-wrap;
}
</style>
</head>
<body>
<div class="container">
<h1>Local AI Text App</h1>
<textarea id="text" placeholder="Enter text here..."></textarea>
<div>
<button onclick="grammar()">Grammar Check</button>
<button onclick="language()">Detect Language</button>
<button onclick="detectAI()">AI Text Detection</button>
<button onclick="generate()">Generate Text</button>
</div>
<h2>Output</h2>
<div class="output" id="output"></div>
</div>
<script>
async function postData(url, data) {
const res = await fetch(url, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
});
return res.json();
}
async function grammar() {
const text = document.getElementById("text").value;
const res = await postData("/grammar", {text});
document.getElementById("output").innerText = res.corrected_text;
}
async function language() {
const text = document.getElementById("text").value;
const res = await postData("/language", {text});
document.getElementById("output").innerText = "Language: " + res.language;
}
async function detectAI() {
const text = document.getElementById("text").value;
const res = await postData("/detect-ai", {text});
document.getElementById("output").innerText = res.result;
}
async function generate() {
const text = document.getElementById("text").value;
const res = await postData("/generate", {prompt: text});
document.getElementById("output").innerText = res.generated_text;
}
</script>
</body>
</html>
"""
@app.route("/", methods=["GET"])
def home():
return render_template_string(HTML_PAGE)
# ======================================================
# API routes
# ======================================================
@app.route("/grammar", methods=["POST"])
def grammar():
return jsonify({
"corrected_text": grammar_check(request.json.get("text", ""))
})
@app.route("/language", methods=["POST"])
def language():
return jsonify({
"language": detect_language(request.json.get("text", ""))
})
@app.route("/generate", methods=["POST"])
def generate():
return jsonify({
"generated_text": generate_text(request.json.get("prompt", ""))
})
@app.route("/detect-ai", methods=["POST"])
def detect_ai():
return jsonify({
"result": ai_text_detector(request.json.get("text", ""))
})
# ======================================================
# Run (Flask dev server – correct for HF Spaces)
# ======================================================
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)