TaruniSwathi commited on
Commit
962dcef
Β·
verified Β·
1 Parent(s): 2af3ad8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +155 -35
app.py CHANGED
@@ -6,15 +6,31 @@ import torch
6
  from transformers import AutoModelForCausalLM, AutoTokenizer
7
 
8
 
 
 
 
 
9
  MODEL_ID = "shibsankardhara2/Qwen2.5-Coder-1.5B-Java-CSharp_V5"
10
 
 
 
 
 
 
11
  print("Loading tokenizer...")
 
12
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
13
 
14
  if tokenizer.pad_token_id is None:
15
  tokenizer.pad_token_id = tokenizer.eos_token_id
16
 
 
 
 
 
 
17
  print("Loading model on CPU...")
 
18
  model = AutoModelForCausalLM.from_pretrained(
19
  MODEL_ID,
20
  torch_dtype=torch.float16,
@@ -22,10 +38,19 @@ model = AutoModelForCausalLM.from_pretrained(
22
  )
23
 
24
  model.eval()
 
25
  print("Model loaded successfully.")
26
 
27
 
 
 
 
 
28
  def add_java_hint(instruction: str) -> str:
 
 
 
 
29
  instruction = instruction.strip()
30
 
31
  if "java" in instruction.lower():
@@ -35,6 +60,9 @@ def add_java_hint(instruction: str) -> str:
35
 
36
 
37
  def build_prompt(task: str, user_input: str) -> str:
 
 
 
38
  user_input = user_input.strip()
39
 
40
  if task == "Natural Language β†’ Java":
@@ -45,16 +73,24 @@ def build_prompt(task: str, user_input: str) -> str:
45
  )
46
 
47
  return (
48
- "### Instruction\n"
49
  "Translate the following Java code into equivalent C#. "
50
- "Write the solution in C#.\n\n"
51
- "### Java\n"
52
  f"{user_input}\n\n"
53
- "### Response\n"
54
  )
55
 
56
 
 
 
 
 
57
  def clean_output(text: str) -> str:
 
 
 
 
58
  text = text.strip()
59
 
60
  fenced = re.search(
@@ -83,39 +119,70 @@ def clean_output(text: str) -> str:
83
 
84
  return text
85
 
86
- def _clean_csharp_output(text: str) -> str:
 
87
  """
88
- Remove spurious `virtual` / `override` modifiers the model adds to bare
89
- (class-less) method snippets.
90
-
91
- The model was trained on C# methods that usually live inside a class, where
92
- `public virtual ...` is common. When it translates a *standalone* Java method
93
- it carries the `virtual` keyword over β€” but `virtual`/`override` are only
94
- valid on members of a class, so on a bare snippet they are invalid C#.
95
- We therefore strip them ONLY when the snippet has no enclosing type
96
- declaration (class / struct / interface / record / enum).
97
  """
98
- if re.search(r"\b(class|struct|interface|record|enum)\b", code):
99
- return code # real type present β€” leave modifiers intact
100
- # Drop 'virtual'/'override' after an access modifier: 'public virtual int' -> 'public int'.
101
- code = re.sub(r"\b(public|private|protected|internal)\s+(?:virtual|override)\s+",
102
- r"\1 ", code)
103
- # Drop a leading 'virtual'/'override' with no access modifier.
104
- code = re.sub(r"(^|\n)(\s*)(?:virtual|override)\s+", r"\1\2", code)
105
- return code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
 
 
 
 
 
 
107
 
108
-
109
  @spaces.GPU(duration=120)
110
  def generate_code(task: str, user_input: str) -> str:
 
 
 
 
111
  if not user_input or not user_input.strip():
112
  return "Please enter a requirement or Java code."
113
 
114
  prompt = build_prompt(task, user_input)
115
 
116
- max_new_tokens = 300 if task == "Natural Language β†’ Java" else 400
 
 
 
117
 
118
  try:
 
119
  model.to("cuda")
120
 
121
  inputs = tokenizer(
@@ -130,35 +197,61 @@ def generate_code(task: str, user_input: str) -> str:
130
  **inputs,
131
  max_new_tokens=max_new_tokens,
132
  do_sample=False,
133
- pad_token_id=tokenizer.eos_token_id,
134
  eos_token_id=tokenizer.eos_token_id,
135
  )
136
 
137
- generated_tokens = outputs[0][inputs["input_ids"].shape[1]:]
 
 
 
138
 
139
  generated_text = tokenizer.decode(
140
  generated_tokens,
141
  skip_special_tokens=True,
142
  )
143
 
144
- code_ = _clean_csharp_output(generated_text)
 
145
 
146
- if not code_:
147
- return "The model returned an empty response. Please try again."
 
 
 
 
148
 
149
- language = "java" if task == "Natural Language β†’ Java" else "csharp"
 
 
 
 
150
 
151
- return f"```{language}\n{code_}\n```"
152
 
153
  except Exception as error:
154
- return f"Generation failed: {type(error).__name__}: {error}"
 
 
 
155
 
156
  finally:
 
157
  model.to("cpu")
158
- torch.cuda.empty_cache()
159
 
 
 
 
 
 
 
 
160
 
161
  def update_input(task: str):
 
 
 
 
162
  if task == "Natural Language β†’ Java":
163
  return gr.update(
164
  label="Natural-language requirement",
@@ -185,6 +278,10 @@ def update_input(task: str):
185
  )
186
 
187
 
 
 
 
 
188
  with gr.Blocks(title="Java and C# CodeGen") as demo:
189
  gr.Markdown(
190
  """
@@ -218,7 +315,9 @@ into equivalent C# using a fine-tuned Qwen2.5-Coder model.
218
  variant="primary",
219
  )
220
 
221
- output = gr.Markdown()
 
 
222
 
223
  task.change(
224
  fn=update_input,
@@ -239,20 +338,38 @@ into equivalent C# using a fine-tuned Qwen2.5-Coder model.
239
  examples=[
240
  [
241
  "Natural Language β†’ Java",
242
- "Write a Java method to calculate factorial of a number using a loop.",
 
 
 
243
  ],
244
  [
245
  "Natural Language β†’ Java",
246
  "Write a Java method to reverse a string.",
247
  ],
 
 
 
 
 
 
 
248
  [
249
  "Java β†’ C#",
250
  """public static int factorial(int n) {
251
  int result = 1;
 
252
  for (int i = 2; i <= n; i++) {
253
  result *= i;
254
  }
 
255
  return result;
 
 
 
 
 
 
256
  }""",
257
  ],
258
  ],
@@ -263,6 +380,9 @@ into equivalent C# using a fine-tuned Qwen2.5-Coder model.
263
  )
264
 
265
 
 
 
 
266
 
267
  if __name__ == "__main__":
268
  demo.queue(
 
6
  from transformers import AutoModelForCausalLM, AutoTokenizer
7
 
8
 
9
+ # ============================================================
10
+ # MODEL CONFIGURATION
11
+ # ============================================================
12
+
13
  MODEL_ID = "shibsankardhara2/Qwen2.5-Coder-1.5B-Java-CSharp_V5"
14
 
15
+
16
+ # ============================================================
17
+ # LOAD TOKENIZER
18
+ # ============================================================
19
+
20
  print("Loading tokenizer...")
21
+
22
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
23
 
24
  if tokenizer.pad_token_id is None:
25
  tokenizer.pad_token_id = tokenizer.eos_token_id
26
 
27
+
28
+ # ============================================================
29
+ # LOAD MODEL
30
+ # ============================================================
31
+
32
  print("Loading model on CPU...")
33
+
34
  model = AutoModelForCausalLM.from_pretrained(
35
  MODEL_ID,
36
  torch_dtype=torch.float16,
 
38
  )
39
 
40
  model.eval()
41
+
42
  print("Model loaded successfully.")
43
 
44
 
45
+ # ============================================================
46
+ # PROMPT FUNCTIONS
47
+ # ============================================================
48
+
49
  def add_java_hint(instruction: str) -> str:
50
+ """
51
+ Add an explicit Java instruction when the user has not
52
+ mentioned Java in the natural-language requirement.
53
+ """
54
  instruction = instruction.strip()
55
 
56
  if "java" in instruction.lower():
 
60
 
61
 
62
  def build_prompt(task: str, user_input: str) -> str:
63
+ """
64
+ Build the appropriate prompt based on the selected task.
65
+ """
66
  user_input = user_input.strip()
67
 
68
  if task == "Natural Language β†’ Java":
 
73
  )
74
 
75
  return (
76
+ "### Instruction:\n\n"
77
  "Translate the following Java code into equivalent C#. "
78
+ "Write only the C# solution.\n\n"
79
+ "### Java:\n\n"
80
  f"{user_input}\n\n"
81
+ "### Response:\n\n"
82
  )
83
 
84
 
85
+ # ============================================================
86
+ # OUTPUT CLEANING
87
+ # ============================================================
88
+
89
  def clean_output(text: str) -> str:
90
+ """
91
+ Remove Markdown code fences, repeated prompt sections,
92
+ and model-specific special tokens from the generated output.
93
+ """
94
  text = text.strip()
95
 
96
  fenced = re.search(
 
119
 
120
  return text
121
 
122
+
123
+ def clean_csharp_output(code: str) -> str:
124
  """
125
+ Remove unnecessary `virtual` and `override` modifiers from
126
+ standalone C# method snippets.
127
+
128
+ These modifiers are preserved when the generated code contains
129
+ a class, struct, interface, record, or enum declaration.
 
 
 
 
130
  """
131
+ code = code.strip()
132
+
133
+ has_type_declaration = re.search(
134
+ r"\b(class|struct|interface|record|enum)\b",
135
+ code,
136
+ flags=re.IGNORECASE,
137
+ )
138
+
139
+ if has_type_declaration:
140
+ return code
141
+
142
+ # Example:
143
+ # public virtual int Add(...) -> public int Add(...)
144
+ code = re.sub(
145
+ r"\b(public|private|protected|internal)\s+"
146
+ r"(?:virtual|override)\s+",
147
+ r"\1 ",
148
+ code,
149
+ flags=re.IGNORECASE,
150
+ )
151
+
152
+ # Example:
153
+ # virtual int Add(...) -> int Add(...)
154
+ code = re.sub(
155
+ r"(^|\n)(\s*)(?:virtual|override)\s+",
156
+ r"\1\2",
157
+ code,
158
+ flags=re.IGNORECASE,
159
+ )
160
 
161
+ return code.strip()
162
+
163
+
164
+ # ============================================================
165
+ # CODE GENERATION
166
+ # ============================================================
167
 
 
168
  @spaces.GPU(duration=120)
169
  def generate_code(task: str, user_input: str) -> str:
170
+ """
171
+ Generate Java code from natural language or translate
172
+ Java code into C#.
173
+ """
174
  if not user_input or not user_input.strip():
175
  return "Please enter a requirement or Java code."
176
 
177
  prompt = build_prompt(task, user_input)
178
 
179
+ if task == "Natural Language β†’ Java":
180
+ max_new_tokens = 300
181
+ else:
182
+ max_new_tokens = 400
183
 
184
  try:
185
+ # Move the model to the GPU only during generation.
186
  model.to("cuda")
187
 
188
  inputs = tokenizer(
 
197
  **inputs,
198
  max_new_tokens=max_new_tokens,
199
  do_sample=False,
200
+ pad_token_id=tokenizer.pad_token_id,
201
  eos_token_id=tokenizer.eos_token_id,
202
  )
203
 
204
+ # Remove the original input prompt from the generated sequence.
205
+ prompt_length = inputs["input_ids"].shape[1]
206
+
207
+ generated_tokens = outputs[0][prompt_length:]
208
 
209
  generated_text = tokenizer.decode(
210
  generated_tokens,
211
  skip_special_tokens=True,
212
  )
213
 
214
+ # Clean repeated prompts, code fences, and special tokens.
215
+ code = clean_output(generated_text)
216
 
217
+ # Apply the C# modifier cleanup only for Java β†’ C#.
218
+ if task == "Java β†’ C#":
219
+ code = clean_csharp_output(code)
220
+ language = "csharp"
221
+ else:
222
+ language = "java"
223
 
224
+ if not code:
225
+ return (
226
+ "The model returned an empty response. "
227
+ "Please try again."
228
+ )
229
 
230
+ return f"```{language}\n{code}\n```"
231
 
232
  except Exception as error:
233
+ return (
234
+ "Generation failed: "
235
+ f"{type(error).__name__}: {error}"
236
+ )
237
 
238
  finally:
239
+ # Move the model back to CPU to release the ZeroGPU allocation.
240
  model.to("cpu")
 
241
 
242
+ if torch.cuda.is_available():
243
+ torch.cuda.empty_cache()
244
+
245
+
246
+ # ============================================================
247
+ # GRADIO INPUT UPDATE
248
+ # ============================================================
249
 
250
  def update_input(task: str):
251
+ """
252
+ Change the textbox label and placeholder based on the
253
+ selected task.
254
+ """
255
  if task == "Natural Language β†’ Java":
256
  return gr.update(
257
  label="Natural-language requirement",
 
278
  )
279
 
280
 
281
+ # ============================================================
282
+ # GRADIO INTERFACE
283
+ # ============================================================
284
+
285
  with gr.Blocks(title="Java and C# CodeGen") as demo:
286
  gr.Markdown(
287
  """
 
315
  variant="primary",
316
  )
317
 
318
+ output = gr.Markdown(
319
+ value="Generated code will appear here."
320
+ )
321
 
322
  task.change(
323
  fn=update_input,
 
338
  examples=[
339
  [
340
  "Natural Language β†’ Java",
341
+ (
342
+ "Write a Java method to calculate factorial "
343
+ "of a number using a loop."
344
+ ),
345
  ],
346
  [
347
  "Natural Language β†’ Java",
348
  "Write a Java method to reverse a string.",
349
  ],
350
+ [
351
+ "Natural Language β†’ Java",
352
+ (
353
+ "Write a Java method to check whether "
354
+ "a number is prime."
355
+ ),
356
+ ],
357
  [
358
  "Java β†’ C#",
359
  """public static int factorial(int n) {
360
  int result = 1;
361
+
362
  for (int i = 2; i <= n; i++) {
363
  result *= i;
364
  }
365
+
366
  return result;
367
+ }""",
368
+ ],
369
+ [
370
+ "Java β†’ C#",
371
+ """public boolean isEven(int n) {
372
+ return n % 2 == 0;
373
  }""",
374
  ],
375
  ],
 
380
  )
381
 
382
 
383
+ # ============================================================
384
+ # START APPLICATION
385
+ # ============================================================
386
 
387
  if __name__ == "__main__":
388
  demo.queue(