Amey9766 commited on
Commit
8602cb1
·
verified ·
1 Parent(s): 54a489d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -44
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  import threading
3
  from typing import List, Dict, Optional
4
 
@@ -16,7 +17,7 @@ device = None
16
  def load_model(hf_access_token: Optional[str] = None):
17
  global tokenizer, model, device
18
 
19
- if tokenizer and model:
20
  return
21
 
22
  device = "cuda" if torch.cuda.is_available() else "cpu"
@@ -45,43 +46,63 @@ def load_model(hf_access_token: Optional[str] = None):
45
  print("✅ Loaded model:", getattr(model.config, "_name_or_path", "unknown"))
46
 
47
 
48
- def build_prompt(system_message: str, history: List[Dict[str, str]], user_message: str) -> str:
49
  """
50
- HARD rules to stop:
51
- - self questioning
52
- - rule narration
53
- - exam-style continuation
54
  """
55
  hard_rules = (
56
  "You are a professional hotel housekeeping assistant.\n"
57
  "STRICT RULES:\n"
58
- "- Answer ONLY the user's question.\n"
59
- "- Do NOT generate follow-up questions.\n"
60
- "- Do NOT mention rules, instructions, or reasoning.\n"
61
- "- Do NOT narrate your thinking.\n"
62
- "- Do NOT continue the conversation on your own.\n"
63
- "- Respond in English only.\n"
64
- "- Output ONLY the final answer.\n"
65
  )
66
 
67
- messages = [{"role": "system", "content": hard_rules}]
68
- messages.extend(history)
69
- messages.append({"role": "user", "content": user_message})
70
 
71
- if hasattr(tokenizer, "apply_chat_template"):
72
- return tokenizer.apply_chat_template(
73
- messages,
74
- tokenize=False,
75
- add_generation_prompt=True,
76
- )
77
-
78
- prompt = hard_rules + "\n"
79
  for m in history:
80
- prompt += f"{m['role'].capitalize()}: {m['content']}\n"
81
- prompt += f"User: {user_message}\nAssistant:"
 
 
 
 
 
 
 
 
82
  return prompt
83
 
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  def respond(
86
  message: str,
87
  history: List[Dict[str, str]],
@@ -93,7 +114,7 @@ def respond(
93
  ):
94
  load_model(hf_token.token if hf_token else None)
95
 
96
- prompt = build_prompt(system_message, history, message)
97
 
98
  inputs = tokenizer(prompt, return_tensors="pt")
99
  inputs = {k: v.to(device) for k, v in inputs.items()}
@@ -104,13 +125,14 @@ def respond(
104
  skip_special_tokens=True,
105
  )
106
 
 
107
  gen_kwargs = dict(
108
  **inputs,
109
  max_new_tokens=int(max_tokens),
110
  do_sample=True,
111
- temperature=0.3, # 🔒 low temperature = less roleplay
112
- top_p=0.85,
113
- repetition_penalty=1.2, # 🔒 stops looping
114
  streamer=streamer,
115
  eos_token_id=tokenizer.eos_token_id,
116
  pad_token_id=tokenizer.eos_token_id,
@@ -119,20 +141,19 @@ def respond(
119
  thread = threading.Thread(target=model.generate, kwargs=gen_kwargs)
120
  thread.start()
121
 
122
- output = ""
123
- for text in streamer:
124
- # HARD STOP if model tries to continue conversation
125
- if any(bad in text.lower() for bad in [
126
- "now let's",
127
- "question:",
128
- "based on the rules",
129
- "according to the rules",
130
- "let us",
131
- ]):
132
  break
133
 
134
- output += text
135
- yield output.strip()
136
 
137
 
138
  chatbot = gr.ChatInterface(
@@ -142,7 +163,7 @@ chatbot = gr.ChatInterface(
142
  description=f"Running model: `{MODEL_ID}`",
143
  additional_inputs=[
144
  gr.Textbox(
145
- value="Provide SOP-style answers for hotel housekeeping staff.",
146
  label="System message",
147
  ),
148
  gr.Slider(1, 1024, value=256, step=1, label="Max new tokens"),
@@ -155,7 +176,6 @@ with gr.Blocks() as demo:
155
  with gr.Sidebar():
156
  gr.LoginButton()
157
  gr.Markdown(f"**Model:** `{MODEL_ID}`")
158
-
159
  chatbot.render()
160
 
161
  if __name__ == "__main__":
 
1
  import os
2
+ import re
3
  import threading
4
  from typing import List, Dict, Optional
5
 
 
17
  def load_model(hf_access_token: Optional[str] = None):
18
  global tokenizer, model, device
19
 
20
+ if tokenizer is not None and model is not None:
21
  return
22
 
23
  device = "cuda" if torch.cuda.is_available() else "cpu"
 
46
  print("✅ Loaded model:", getattr(model.config, "_name_or_path", "unknown"))
47
 
48
 
49
+ def build_plain_prompt(system_message: str, history: List[Dict[str, str]], user_message: str) -> str:
50
  """
51
+ Universal prompt builder that does NOT require tokenizer.chat_template.
52
+ This works with any CausalLM.
 
 
53
  """
54
  hard_rules = (
55
  "You are a professional hotel housekeeping assistant.\n"
56
  "STRICT RULES:\n"
57
+ "1) Respond in English only.\n"
58
+ "2) Answer ONLY the user's last question.\n"
59
+ "3) Do NOT generate follow-up questions.\n"
60
+ "4) Do NOT mention rules, instructions, or your reasoning.\n"
61
+ "5) Provide only the final answer.\n"
 
 
62
  )
63
 
64
+ sys = (system_message or "").strip()
65
+ prompt = f"{hard_rules}\nSYSTEM NOTE: {sys}\n\n"
 
66
 
67
+ # Convert Gradio "messages" history into a readable transcript
 
 
 
 
 
 
 
68
  for m in history:
69
+ role = (m.get("role") or "user").lower()
70
+ content = (m.get("content") or "").strip()
71
+ if not content:
72
+ continue
73
+ if role == "user":
74
+ prompt += f"User: {content}\n"
75
+ else:
76
+ prompt += f"Assistant: {content}\n"
77
+
78
+ prompt += f"User: {user_message.strip()}\nAssistant:"
79
  return prompt
80
 
81
 
82
+ def clean_output(text: str) -> str:
83
+ """
84
+ Removes common fine-tune artifacts without being too aggressive.
85
+ """
86
+ # Remove leading parenthetical meta like: "(Answering in English...)"
87
+ text = re.sub(r"^\s*\(.*?\)\s*", "", text, flags=re.DOTALL)
88
+
89
+ # If the model starts adding "Question:" sections, cut everything after it
90
+ cut_markers = [
91
+ "\nQuestion:",
92
+ "\nNow, let's",
93
+ "\nNow let's",
94
+ "\nBased on the rules",
95
+ "\nAccording to the rules",
96
+ ]
97
+ for marker in cut_markers:
98
+ idx = text.lower().find(marker.lower())
99
+ if idx != -1:
100
+ text = text[:idx].strip()
101
+ break
102
+
103
+ return text.strip()
104
+
105
+
106
  def respond(
107
  message: str,
108
  history: List[Dict[str, str]],
 
114
  ):
115
  load_model(hf_token.token if hf_token else None)
116
 
117
+ prompt = build_plain_prompt(system_message, history, message)
118
 
119
  inputs = tokenizer(prompt, return_tensors="pt")
120
  inputs = {k: v.to(device) for k, v in inputs.items()}
 
125
  skip_special_tokens=True,
126
  )
127
 
128
+ # Lower randomness to reduce “roleplay / training artifact” behavior
129
  gen_kwargs = dict(
130
  **inputs,
131
  max_new_tokens=int(max_tokens),
132
  do_sample=True,
133
+ temperature=float(temperature),
134
+ top_p=float(top_p),
135
+ repetition_penalty=1.15,
136
  streamer=streamer,
137
  eos_token_id=tokenizer.eos_token_id,
138
  pad_token_id=tokenizer.eos_token_id,
 
141
  thread = threading.Thread(target=model.generate, kwargs=gen_kwargs)
142
  thread.start()
143
 
144
+ out = ""
145
+ for chunk in streamer:
146
+ out += chunk
147
+
148
+ # Stream the cleaned output live
149
+ cleaned = clean_output(out)
150
+
151
+ # Hard stop if it starts self-questioning
152
+ if any(x in out.lower() for x in ["\nquestion:", "now, let's generate", "based on the rules"]):
153
+ yield cleaned
154
  break
155
 
156
+ yield cleaned
 
157
 
158
 
159
  chatbot = gr.ChatInterface(
 
163
  description=f"Running model: `{MODEL_ID}`",
164
  additional_inputs=[
165
  gr.Textbox(
166
+ value="Give SOP-style housekeeping answers. Use bullet points when helpful.",
167
  label="System message",
168
  ),
169
  gr.Slider(1, 1024, value=256, step=1, label="Max new tokens"),
 
176
  with gr.Sidebar():
177
  gr.LoginButton()
178
  gr.Markdown(f"**Model:** `{MODEL_ID}`")
 
179
  chatbot.render()
180
 
181
  if __name__ == "__main__":