karths commited on
Commit
f2865c2
·
verified ·
1 Parent(s): 3d49ad2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -57
app.py CHANGED
@@ -57,21 +57,7 @@ models = {path: AutoModelForSequenceClassification.from_pretrained(path) for pat
57
  def get_quality_name(model_name):
58
  return quality_mapping.get(model_name.split('/')[-1], "Unknown Quality")
59
 
60
- def model_prediction(model, text, device):
61
- """Optimized: Using inference_mode and keeping models on GPU during the loop."""
62
- model.to(device)
63
- model.eval()
64
- inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
65
- inputs = {k: v.to(device) for k, v in inputs.items()}
66
-
67
- with torch.inference_mode():
68
- outputs = model(**inputs)
69
- logits = outputs.logits
70
- probs = softmax(logits.cpu().numpy(), axis=1)
71
-
72
- avg_prob = np.mean(probs[:, 1])
73
- return avg_prob
74
-
75
  azure_api_key = os.getenv("AZURE_OPENAI_API_KEY")
76
 
77
  if not azure_api_key:
@@ -85,9 +71,9 @@ azure_client = AzureOpenAI(
85
  azure_deployment_name = "gpt-5.4-nano-AM-karthik-prod"
86
 
87
  def generate_explanation(issue_text, top_quality):
88
- """Generates an explanation using Azure OpenAI."""
89
  if not top_quality:
90
- return "<div style='color: red;'>No explanation available as no quality tags met the threshold.</div>"
91
 
92
  quality_name = top_quality[0][0]
93
 
@@ -110,47 +96,65 @@ Provide your response directly without preamble. Use a clear separation between
110
  {"role": "system", "content": "You are an expert software engineering assistant specializing in software quality analysis."},
111
  {"role": "user", "content": prompt}
112
  ],
113
- max_completion_tokens=250, # <--- FIXED HERE
114
  temperature=0.2,
115
  top_p=0.9
116
  )
117
  explanation = response.choices[0].message.content.strip()
118
- formatted_explanation = f"<div class='explanation-box'>\n\n### Why this is a {quality_name} issue:\n\n{explanation}\n\n</div>"
 
 
119
  return formatted_explanation
120
 
121
  except Exception as e:
122
  logging.error(f"Error during Azure OpenAI generation: {e}")
123
- return "<div style='color: red;'>An error occurred while communicating with the Azure OpenAI service. Please check the logs.</div>"
124
 
125
  @spaces.GPU(duration=60)
126
- def main_interface(text):
127
- if not text.strip():
128
- return "<div style='color: red;'>No text provided. Please enter a valid issue description.</div>", "", ""
129
-
130
- if len(text) < 30:
131
- return "<div style='color: red;'>Text is less than 30 characters.</div>", "", ""
132
-
133
  device = "cuda" if torch.cuda.is_available() else "cpu"
134
  results = []
135
 
136
  for model_path, model in models.items():
 
 
 
 
 
 
 
 
 
 
 
137
  quality_name = get_quality_name(model_path)
138
- avg_prob = model_prediction(model, text, device)
139
  if avg_prob >= 0.95:
140
  results.append((quality_name, avg_prob))
141
- logging.info(f"Model: {model_path}, Quality: {quality_name}, Average Probability: {avg_prob:.3f}")
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  if not results:
144
  return "<div style='color: red;'>No recommendation. Prediction probability is below the threshold.</div>", "", ""
145
 
 
146
  top_result = sorted(results, key=lambda x: x[1], reverse=True)
147
- if top_result:
148
- top_quality = top_result[:1]
149
- output_html = render_html_output(top_quality)
150
- explanation = generate_explanation(text, top_quality)
151
- else:
152
- output_html = "<div style='color: red;'>No quality tag met the prediction probability threshold (>= 0.95).</div>"
153
- explanation = ""
154
 
155
  return output_html, "", explanation
156
 
@@ -174,6 +178,7 @@ example_texts = [
174
  ["The service-oriented architecture does not effectively isolate failures, leading to cascading failures across services.\n\nEnvironment: Microservices architecture\nReproduction: Simulate a service failure and observe the impact on other services."]
175
  ]
176
 
 
177
  css = """
178
  .quality-container {
179
  font-family: Arial, sans-serif;
@@ -198,23 +203,16 @@ css = """
198
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
199
  }
200
 
 
201
  .explanation-box {
202
- border: 1px solid var(--border-color-primary, #ccc);
203
- padding: 15px;
204
- margin-top: 15px;
205
- border-radius: 8px;
206
- background-color: var(--background-fill-primary, #fff);
207
- color: var(--body-text-color, #000);
208
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
209
- line-height: 1.5;
210
- }
211
-
212
- .explanation-box p {
213
- margin: 8px 0;
214
- }
215
-
216
- .explanation-box b {
217
- color: #007bff;
218
  }
219
 
220
  .dark .quality-container {
@@ -224,20 +222,22 @@ css = """
224
  }
225
 
226
  .dark .explanation-box {
227
- background-color: #1f2937;
228
- border-color: #374151;
229
- color: #f3f4f6;
230
- box-shadow: 0 1px 3px rgba(255,255,255,0.05);
231
  }
232
  """
233
 
234
  interface = gr.Interface(
 
235
  fn=main_interface,
236
  inputs=gr.Textbox(lines=7, label="Issue Description", placeholder="Enter your issue text here"),
237
  outputs=[
238
  gr.HTML(label="Prediction Output"),
239
  gr.Textbox(label="Predictions", visible=False),
240
- gr.Markdown(label="Explanation")
 
241
  ],
242
  title="QualityTagger",
243
  description="This tool classifies text into different quality domains such as Security, Usability, Maintainability, Reliability etc., and provides explanations.",
 
57
  def get_quality_name(model_name):
58
  return quality_mapping.get(model_name.split('/')[-1], "Unknown Quality")
59
 
60
+ # --- Azure OpenAI Setup ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  azure_api_key = os.getenv("AZURE_OPENAI_API_KEY")
62
 
63
  if not azure_api_key:
 
71
  azure_deployment_name = "gpt-5.4-nano-AM-karthik-prod"
72
 
73
  def generate_explanation(issue_text, top_quality):
74
+ """Generates an explanation using Azure OpenAI (Pure Markdown output)"""
75
  if not top_quality:
76
+ return "**No explanation available** as no quality tags met the threshold."
77
 
78
  quality_name = top_quality[0][0]
79
 
 
96
  {"role": "system", "content": "You are an expert software engineering assistant specializing in software quality analysis."},
97
  {"role": "user", "content": prompt}
98
  ],
99
+ max_completion_tokens=250,
100
  temperature=0.2,
101
  top_p=0.9
102
  )
103
  explanation = response.choices[0].message.content.strip()
104
+
105
+ # FIX 1: Return pure markdown. Do not wrap in HTML <div> tags.
106
+ formatted_explanation = f"### Why this is a {quality_name} issue:\n\n{explanation}"
107
  return formatted_explanation
108
 
109
  except Exception as e:
110
  logging.error(f"Error during Azure OpenAI generation: {e}")
111
+ return f"**Error:** An error occurred while communicating with the Azure OpenAI service: {e}"
112
 
113
  @spaces.GPU(duration=60)
114
+ def run_classification_models(text):
115
+ """FIX 2: Isolate the GPU work so we aren't holding the GPU while waiting for the network API call."""
 
 
 
 
 
116
  device = "cuda" if torch.cuda.is_available() else "cpu"
117
  results = []
118
 
119
  for model_path, model in models.items():
120
+ model.to(device)
121
+ model.eval()
122
+ inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
123
+ inputs = {k: v.to(device) for k, v in inputs.items()}
124
+
125
+ with torch.inference_mode():
126
+ outputs = model(**inputs)
127
+ logits = outputs.logits
128
+ probs = softmax(logits.cpu().numpy(), axis=1)
129
+
130
+ avg_prob = np.mean(probs[:, 1])
131
  quality_name = get_quality_name(model_path)
132
+
133
  if avg_prob >= 0.95:
134
  results.append((quality_name, avg_prob))
135
+
136
+ return results
137
+
138
+ def main_interface(text):
139
+ if not text.strip():
140
+ return "<div style='color: red;'>No text provided. Please enter a valid issue description.</div>", "", ""
141
+
142
+ if len(text) < 30:
143
+ return "<div style='color: red;'>Text is less than 30 characters.</div>", "", ""
144
+
145
+ # 1. Run the GPU models
146
+ results = run_classification_models(text)
147
 
148
  if not results:
149
  return "<div style='color: red;'>No recommendation. Prediction probability is below the threshold.</div>", "", ""
150
 
151
+ # 2. Process results
152
  top_result = sorted(results, key=lambda x: x[1], reverse=True)
153
+ top_quality = top_result[:1]
154
+ output_html = render_html_output(top_quality)
155
+
156
+ # 3. Fetch the OpenAI Explanation (Safely running on CPU/Network, off the ZeroGPU queue)
157
+ explanation = generate_explanation(text, top_quality)
 
 
158
 
159
  return output_html, "", explanation
160
 
 
178
  ["The service-oriented architecture does not effectively isolate failures, leading to cascading failures across services.\n\nEnvironment: Microservices architecture\nReproduction: Simulate a service failure and observe the impact on other services."]
179
  ]
180
 
181
+ # FIX 3: We apply styles directly to Gradio's components using !important overrides
182
  css = """
183
  .quality-container {
184
  font-family: Arial, sans-serif;
 
203
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
204
  }
205
 
206
+ /* Updated: Target the Markdown component natively */
207
  .explanation-box {
208
+ border: 1px solid var(--border-color-primary, #ccc) !important;
209
+ padding: 15px !important;
210
+ margin-top: 15px !important;
211
+ border-radius: 8px !important;
212
+ background-color: var(--background-fill-primary, #fff) !important;
213
+ color: var(--body-text-color, #000) !important;
214
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
215
+ line-height: 1.5 !important;
 
 
 
 
 
 
 
 
216
  }
217
 
218
  .dark .quality-container {
 
222
  }
223
 
224
  .dark .explanation-box {
225
+ background-color: #1f2937 !important;
226
+ border-color: #374151 !important;
227
+ color: #f3f4f6 !important;
228
+ box-shadow: 0 1px 3px rgba(255,255,255,0.05) !important;
229
  }
230
  """
231
 
232
  interface = gr.Interface(
233
+ # Note: main_interface is no longer @spaces.GPU wrapped!
234
  fn=main_interface,
235
  inputs=gr.Textbox(lines=7, label="Issue Description", placeholder="Enter your issue text here"),
236
  outputs=[
237
  gr.HTML(label="Prediction Output"),
238
  gr.Textbox(label="Predictions", visible=False),
239
+ # FIX 4: Add the CSS class natively to the Markdown block
240
+ gr.Markdown(label="Explanation", elem_classes="explanation-box")
241
  ],
242
  title="QualityTagger",
243
  description="This tool classifies text into different quality domains such as Security, Usability, Maintainability, Reliability etc., and provides explanations.",