Spaces:
Sleeping
Sleeping
| import uvicorn | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel | |
| # QUAN TRỌNG: Import XLMRobertaForTokenClassification để fix lỗi "Unrecognized model" | |
| from transformers import AutoTokenizer, XLMRobertaForTokenClassification, pipeline | |
| import torch | |
| import time | |
| app = FastAPI() | |
| MODEL_PATH = "fallinluv8/nexore-toxic-model" | |
| # Bạn có thể thêm từ vào đây tùy ý | |
| HARD_BLACKLIST = [ | |
| "đéo", "đ**", "dm", "dcm", "đm", "vcl", "vl", | |
| "cc", "cmn", "cmm", "lồn", "l**", "đĩ", "đ**", | |
| "cặc", "c**", "buồi", "bu**", "đụ", "đụ mẹ", | |
| "đụ bố", "đụ con mẹ mày", "đụ con", "đụ mày" | |
| ] | |
| classifier = None | |
| startup_error = None | |
| def load_model(): | |
| global classifier, startup_error | |
| print(f" [STARTUP] Đang tải Model từ Hub: {MODEL_PATH}...") | |
| try: | |
| # Load Tokenizer | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH) | |
| model = XLMRobertaForTokenClassification.from_pretrained(MODEL_PATH) | |
| classifier = pipeline( | |
| "token-classification", | |
| model=model, | |
| tokenizer=tokenizer, | |
| aggregation_strategy="simple", | |
| device=-1 # Chạy CPU | |
| ) | |
| print(" [STARTUP] Model đã tải thành công!") | |
| startup_error = None | |
| except Exception as e: | |
| startup_error = str(e) | |
| print(f" [STARTUP] Lỗi tải model: {e}") | |
| class ToxicRequest(BaseModel): | |
| text: str | |
| def home(): | |
| # Nếu có lỗi khởi động, hiển thị ra ngay trang chủ để dễ debug | |
| if startup_error: | |
| return { | |
| "status": "Model Failed to Load", | |
| "error": startup_error, | |
| "suggestion": "Check config.json or use XLMRobertaForTokenClassification" | |
| } | |
| status = "Ready" if classifier else "Loading..." | |
| return {"status": f"AI NER Service is {status}"} | |
| async def predict_toxicity(request: ToxicRequest): | |
| global classifier | |
| # Nếu model chưa tải xong hoặc bị lỗi, báo ngay | |
| if classifier is None: | |
| detail = startup_error if startup_error else "Model is loading..." | |
| raise HTTPException(status_code=503, detail=f"Service unavailable: {detail}") | |
| if not request.text: | |
| raise HTTPException(status_code=400, detail="Thiếu nội dung text") | |
| text_lower = request.text.lower() | |
| is_toxic = False | |
| max_score = 0.0 | |
| toxic_words = [] | |
| # 1. CHECK BLACKLIST (Luôn kiểm tra trước cho nhanh) | |
| for bad_word in HARD_BLACKLIST: | |
| if bad_word in text_lower: | |
| is_toxic = True | |
| max_score = 1.0 | |
| if not any(t['word'] == bad_word for t in toxic_words): | |
| toxic_words.append({ | |
| "word": bad_word, | |
| "score": 1.0 | |
| }) | |
| # 2. CHECK AI MODEL | |
| # Chỉ chạy AI nếu blacklist chưa bắt được hoặc để bổ sung thêm từ vi phạm | |
| try: | |
| results = classifier(request.text) | |
| print(f" [AI SEE] {results}") # Log để debug | |
| for entity in results: | |
| score = float(entity['score']) | |
| word = entity['word'] | |
| group = entity['entity_group'] | |
| # Logic: Lấy các nhãn BAD, TOXIC hoặc LABEL_1 (tùy model train ra cái gì) | |
| if group in ['BAD', 'TOXIC', 'LABEL_1'] and score > 0.6: | |
| if not any(t['word'].lower() == word.lower() for t in toxic_words): | |
| toxic_words.append({ | |
| "word": word, | |
| "score": score | |
| }) | |
| if score > max_score: | |
| max_score = score | |
| # Nếu AI tìm thấy từ có độ tin cậy cao | |
| if max_score > 0.9: | |
| is_toxic = True | |
| except Exception as e: | |
| print(f" [AI ERROR] {e}") | |
| # Nếu blacklist đã bắt được thì bỏ qua lỗi AI, trả về kết quả blacklist | |
| if not is_toxic: | |
| raise HTTPException(status_code=500, detail=f"AI Error: {str(e)}") | |
| return { | |
| "is_toxic": is_toxic, | |
| "score": float(max_score), | |
| "toxic_words": toxic_words | |
| } | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |