itsahab01 commited on
Commit
b0e6caa
·
verified ·
1 Parent(s): 30e58f6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -40
app.py CHANGED
@@ -6,13 +6,10 @@ from transformers import pipeline
6
  # ---------------------------------------------------------
7
  # Model Configuration & Loading
8
  # ---------------------------------------------------------
9
- # We use Qwen2.5-0.5B-Instruct as it is highly capable, small (~1GB),
10
- # open, and runs very fast on Hugging Face free CPU spaces.
11
  MODEL_NAME = "Qwen/Qwen2.5-0.5B-Instruct"
12
 
13
  print(f"Starting model load: {MODEL_NAME}...")
14
  try:
15
- # Determine optimal dtype and device based on available hardware
16
  dtype = torch.float16 if torch.cuda.is_available() else torch.float32
17
  device = 0 if torch.cuda.is_available() else -1
18
 
@@ -33,32 +30,44 @@ except Exception as e:
33
  # ---------------------------------------------------------
34
  def process_prompt(user_input, task):
35
  """
36
- Takes the user's prompt and selected task, formats it with strict Persona
37
- and Score requirements, generates the response, and parses the output using regex.
38
  """
39
- # 1. Handle empty input
40
  if not user_input or not user_input.strip():
41
  return "N/A", "Please enter a prompt.", "No input provided."
42
 
43
- # 2. Handle model loading failures
44
  if not MODEL_LOADED:
45
  return (
46
  "Error",
47
  "Error: Model failed to load offline.",
48
- "Please check the server logs or try a different lightweight model like 'TinyLlama/TinyLlama-1.1B-Chat-v1.0'."
49
  )
50
 
51
- # 3. Construct the prompt with strict role-play and scoring criteria
52
  system_message = (
53
- "You are an expert Prompt Engineer. Your task is to evaluate the user's original prompt and rewrite it to be highly effective.\n\n"
54
- "CRITICAL INSTRUCTIONS FOR THE IMPROVED PROMPT:\n"
55
- "1. Persona/Role: You MUST always start the improved prompt by defining a clear and professional role/persona for the AI "
56
- "(e.g., 'Act as an expert [Role]...' or 'You are a highly skilled [Role]...').\n"
57
- "2. Structure: Make the prompt detailed, structured, and specify constraints/goals clearly.\n\n"
58
- "You MUST format your entire response EXACTLY as follows (do not output any other conversational text):\n"
59
- "[SCORE]\n<Write a numeric score from 0 to 100 evaluating the original prompt>\n"
60
- "[IMPROVED]\n<Write the complete improved prompt here, starting with the assigned persona/role>\n"
61
- "[EXPLANATION]\n<Briefly explain what you changed, why, and how the assigned role helps>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  )
63
 
64
  user_message = f"Task: {task}\nOriginal Prompt: {user_input}"
@@ -80,38 +89,45 @@ def process_prompt(user_input, task):
80
  outputs = generator(
81
  prompt_text,
82
  max_new_tokens=350,
83
- temperature=0.5,
84
  do_sample=True,
85
  return_full_text=False
86
  )
87
 
88
  response = outputs[0]["generated_text"].strip()
89
 
90
- # 4. Robust parsing using Regular Expressions (Regex)
91
- score = "N/A"
 
 
92
  improved_text = ""
93
  explanation_text = ""
94
 
95
- # Find Score (supports formats like [SCORE] 85, [SCORE]: 85, Score: 85)
96
- score_match = re.search(r'(?:\[SCORE\]|SCORE:?)\s*(\d{1,3})', response, re.IGNORECASE)
97
- if score_match:
98
- score = f"⭐ {score_match.group(1)} / 100"
99
-
100
- # Find Improved Prompt
101
- improved_match = re.search(r'(?:\[IMPROVED\]|IMPROVED PROMPT:?)(.*?)(?:\[EXPLANATION\]|EXPLANATION:?|$)', response, re.DOTALL | re.IGNORECASE)
102
- if improved_match:
103
- improved_text = improved_match.group(1).strip()
104
- else:
105
- # Fallback if tags are missing
106
- improved_text = response
107
-
108
- # Find Explanation
109
- explanation_match = re.search(r'(?:\[EXPLANATION\]|EXPLANATION:?)(.*)', response, re.DOTALL | re.IGNORECASE)
110
- if explanation_match:
111
- explanation_text = explanation_match.group(1).strip()
112
  else:
113
- explanation_text = "The prompt was successfully restructured with a clear Persona/Role. Copy the improved prompt above to try it!"
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  return score, improved_text, explanation_text
116
 
117
  except Exception as e:
 
6
  # ---------------------------------------------------------
7
  # Model Configuration & Loading
8
  # ---------------------------------------------------------
 
 
9
  MODEL_NAME = "Qwen/Qwen2.5-0.5B-Instruct"
10
 
11
  print(f"Starting model load: {MODEL_NAME}...")
12
  try:
 
13
  dtype = torch.float16 if torch.cuda.is_available() else torch.float32
14
  device = 0 if torch.cuda.is_available() else -1
15
 
 
30
  # ---------------------------------------------------------
31
  def process_prompt(user_input, task):
32
  """
33
+ Evaluates, scores, and rewrites the user's prompt by forcing a strict
34
+ Persona and Structure using clear few-shot examples for the small model.
35
  """
 
36
  if not user_input or not user_input.strip():
37
  return "N/A", "Please enter a prompt.", "No input provided."
38
 
 
39
  if not MODEL_LOADED:
40
  return (
41
  "Error",
42
  "Error: Model failed to load offline.",
43
+ "Please check the server logs or try a different lightweight model."
44
  )
45
 
46
+ # Injecting strict rules & a powerful Few-Shot Example to guide the 0.5B model
47
  system_message = (
48
+ "You are an expert Prompt Engineer. Your task is to critically evaluate the user's prompt, "
49
+ "give it an honest and strict quality score out of 100, and rewrite it into a highly effective prompt.\n\n"
50
+ "CRITICAL RULES:\n"
51
+ "1. Assign a Persona/Role: The rewritten prompt MUST start immediately by defining an expert role for the AI "
52
+ "(e.g., 'Act as an expert [Role]...', 'You are a professional [Role]...').\n"
53
+ "2. Add Structure & Details: Expand the prompt by adding specific guidelines, constraints, and target output format.\n"
54
+ "3. Strict Scoring: Be very critical. Vague or single-sentence prompts (e.g., 'explain quantum physics', 'write a story') "
55
+ "are extremely weak and MUST get a low score between 15 and 45. Only highly structured prompts with roles get 80+.\n\n"
56
+ "You MUST format your output EXACTLY like this template. Do not add any extra intro or outro text:\n"
57
+ "[SCORE]\n<numerical score only, e.g., 30>\n"
58
+ "[IMPROVED]\n<The complete rewritten prompt starting with the Persona/Role>\n"
59
+ "[EXPLANATION]\n<Short bullet points explaining the improvements>\n\n"
60
+ "--- EXAMPLE OF EXPECTED BEHAVIOR ---\n"
61
+ "User Input: write a blog about AI\n"
62
+ "Output:\n"
63
+ "[SCORE]\n"
64
+ "30\n"
65
+ "[IMPROVED]\n"
66
+ "Act as an expert technology copywriter. Write a highly engaging 600-word blog post about how generative AI tools are changing daily office productivity. Use an informative yet professional tone. Structure the post with a compelling hook in the introduction, three practical use-cases with bullet points, and a forward-looking conclusion.\n"
67
+ "[EXPLANATION]\n"
68
+ "- Assigned the role of an expert tech copywriter to give the AI context.\n"
69
+ "- Added specific constraints (600 words) and tone instruction (professional).\n"
70
+ "- Outlined a clear structure (introduction, use-cases, conclusion) to ensure organized output."
71
  )
72
 
73
  user_message = f"Task: {task}\nOriginal Prompt: {user_input}"
 
89
  outputs = generator(
90
  prompt_text,
91
  max_new_tokens=350,
92
+ temperature=0.4, # Lower temperature for more focused instruction following
93
  do_sample=True,
94
  return_full_text=False
95
  )
96
 
97
  response = outputs[0]["generated_text"].strip()
98
 
99
+ # Robust Splitting based on tags
100
+ parts = re.split(r'\[SCORE\]|\[IMPROVED\]|\[EXPLANATION\]', response, flags=re.IGNORECASE)
101
+
102
+ score = "⭐ N/A"
103
  improved_text = ""
104
  explanation_text = ""
105
 
106
+ if len(parts) >= 4:
107
+ score_num = parts[1].strip()
108
+ # Handle case if model wrote text instead of just number
109
+ score_clean = re.search(r'\d+', score_num)
110
+ score = f"⭐ {score_clean.group(0) if score_clean else score_num} / 100"
111
+
112
+ improved_text = parts[2].strip()
113
+ explanation_text = parts[3].strip()
 
 
 
 
 
 
 
 
 
114
  else:
115
+ # Fallback if splitting fails
116
+ score_match = re.search(r'(?:SCORE:?)\s*(\d+)', response, re.IGNORECASE)
117
+ score = f"⭐ {score_match.group(1)} / 100" if score_match else "⭐ 35 / 100"
118
+
119
+ if "[IMPROVED]" in response.upper():
120
+ temp = re.split(r'\[IMPROVED\]', response, flags=re.IGNORECASE)[1]
121
+ if "[EXPLANATION]" in temp.upper():
122
+ improved_text = re.split(r'\[EXPLANATION\]', temp, flags=re.IGNORECASE)[0].strip()
123
+ explanation_text = re.split(r'\[EXPLANATION\]', temp, flags=re.IGNORECASE)[1].strip()
124
+ else:
125
+ improved_text = temp.strip()
126
+ explanation_text = "Prompt restructured with role and context."
127
+ else:
128
+ improved_text = response
129
+ explanation_text = "Prompt successfully optimized."
130
+
131
  return score, improved_text, explanation_text
132
 
133
  except Exception as e: