AsyncCoder-10 commited on
Commit
e7af17d
·
verified ·
1 Parent(s): ba14071

Update app/main.py

Browse files
Files changed (1) hide show
  1. app/main.py +46 -36
app/main.py CHANGED
@@ -1,24 +1,17 @@
 
 
 
 
 
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
  from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
4
  from glin_profanity import Filter
5
  import re
 
6
 
7
- # 1. Toxicity classifier
8
  toxicity_pipe = pipeline("text-classification", model="textdetox/twitter-xlmr-toxicity-classifier")
9
-
10
- # 2. Phi-3 Model - The FIX is here
11
- model_id = "microsoft/Phi-3-mini-4k-instruct"
12
- tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
13
- model = AutoModelForCausalLM.from_pretrained(
14
- model_id,
15
- trust_remote_code=True,
16
- attn_implementation="eager", # Solves the window_size error
17
- device_map="auto", # Requires accelerate
18
- torch_dtype="auto", # Use the best dtype automatically
19
- )
20
- llm_pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
21
-
22
  profanity_filter = Filter({"languages": ["english", "spanish", "french"], "replace_with": "***"})
23
 
24
  app = FastAPI(title="Multilingual Moderation API")
@@ -39,6 +32,44 @@ THREAT_KEYWORDS = [
39
  ]
40
  threat_pattern = re.compile("|".join(THREAT_KEYWORDS), re.IGNORECASE)
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  @app.post("/moderate", response_model=ModerationResponse)
43
  async def moderate_text(request: TextRequest):
44
  text = request.text
@@ -57,28 +88,7 @@ async def moderate_text(request: TextRequest):
57
 
58
  rewritten = None
59
  if is_flagged:
60
- messages = [
61
- {"role": "system", "content": "You are a helpful, polite assistant. Rewrite the user's toxic message into exactly 5 different safe, polite, and non-threatening sentences. Number them 1 to 5. Do not include any other text in your response."},
62
- {"role": "user", "content": text}
63
- ]
64
-
65
- prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
66
- outputs = llm_pipe(prompt, max_new_tokens=200, do_sample=True, temperature=0.7)
67
- generated_text = outputs[0]['generated_text'][len(prompt):].strip()
68
-
69
- lines = generated_text.split('\n')
70
- rewritten = []
71
- for line in lines:
72
- line = line.strip()
73
- if line and line[0].isdigit():
74
- clean_line = re.sub(r'^\d+[\.\-\)]\s*', '', line).strip()
75
- clean_line = clean_line.strip('"\'')
76
- if clean_line:
77
- rewritten.append(clean_line)
78
-
79
- rewritten = list(dict.fromkeys(rewritten))[:5]
80
- if not rewritten:
81
- rewritten = ["[AI could not generate a rewrite, please revise manually]"]
82
 
83
  return ModerationResponse(
84
  original_text=text,
 
1
+ import os
2
+ os.environ.setdefault("NUMBA_DISABLE_CUDA", "1") # Prevents numba.cuda from initializing CUDA early
3
+
4
+ import spaces # Must come before any torch imports
5
+
6
  from fastapi import FastAPI
7
  from pydantic import BaseModel
8
  from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
9
  from glin_profanity import Filter
10
  import re
11
+ import torch
12
 
13
+ # Toxicity classifier — can stay at module level (CPU-based)
14
  toxicity_pipe = pipeline("text-classification", model="textdetox/twitter-xlmr-toxicity-classifier")
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  profanity_filter = Filter({"languages": ["english", "spanish", "french"], "replace_with": "***"})
16
 
17
  app = FastAPI(title="Multilingual Moderation API")
 
32
  ]
33
  threat_pattern = re.compile("|".join(THREAT_KEYWORDS), re.IGNORECASE)
34
 
35
+ @spaces.GPU
36
+ def generate_suggestions(text: str) -> list[str]:
37
+ """Load Phi-3 and generate rewritten sentences on GPU."""
38
+ model_id = "microsoft/Phi-3-mini-4k-instruct"
39
+ tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
40
+ model = AutoModelForCausalLM.from_pretrained(
41
+ model_id,
42
+ trust_remote_code=True,
43
+ attn_implementation="eager", # Solves the window_size error
44
+ ).to("cuda") # Use .to("cuda"), NOT device_map="auto"
45
+
46
+ messages = [
47
+ {"role": "system", "content": "You are a helpful, polite assistant. Rewrite the user's toxic message into exactly 5 different safe, polite, and non-threatening sentences. Number them 1 to 5. Do not include any other text in your response."},
48
+ {"role": "user", "content": text}
49
+ ]
50
+
51
+ prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
52
+ outputs = model.generate(
53
+ **tokenizer(prompt, return_tensors="pt").to("cuda"),
54
+ max_new_tokens=200,
55
+ do_sample=True,
56
+ temperature=0.7,
57
+ )
58
+ generated_text = tokenizer.decode(outputs[0][len(tokenizer(prompt)["input_ids"]):], skip_special_tokens=True).strip()
59
+
60
+ lines = generated_text.split('\n')
61
+ rewritten = []
62
+ for line in lines:
63
+ line = line.strip()
64
+ if line and line[0].isdigit():
65
+ clean_line = re.sub(r'^\d+[\.\-\)]\s*', '', line).strip()
66
+ clean_line = clean_line.strip('"\'')
67
+ if clean_line:
68
+ rewritten.append(clean_line)
69
+
70
+ rewritten = list(dict.fromkeys(rewritten))[:5]
71
+ return rewritten if rewritten else ["[AI could not generate a rewrite, please revise manually]"]
72
+
73
  @app.post("/moderate", response_model=ModerationResponse)
74
  async def moderate_text(request: TextRequest):
75
  text = request.text
 
88
 
89
  rewritten = None
90
  if is_flagged:
91
+ rewritten = generate_suggestions(text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  return ModerationResponse(
94
  original_text=text,