TaruniSwathi's picture
Update app.py
dfffab1 verified
Raw
History Blame Contribute Delete
11.2 kB
import re
import gradio as gr
import spaces
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# ============================================================
# MODEL CONFIGURATION
# ============================================================
MODEL_ID = "shibsankardhara2/Qwen2.5-Coder-1.5B-Java-CSharp_V5"
# ============================================================
# LOAD TOKENIZER
# ============================================================
print("Loading tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(
MODEL_ID,
trust_remote_code=True,
)
if tokenizer.pad_token_id is None:
tokenizer.pad_token_id = tokenizer.eos_token_id
# ============================================================
# LOAD MODEL ON CPU
# ============================================================
print("Loading model on CPU...")
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.float16,
low_cpu_mem_usage=True,
trust_remote_code=True,
)
model.eval()
print("Model loaded successfully.")
# ============================================================
# PROMPT FUNCTIONS
# ============================================================
def add_java_hint(instruction: str) -> str:
"""
Explicitly mention Java when it is missing from the
natural-language instruction.
"""
instruction = instruction.strip()
if "java" in instruction.lower():
return instruction
return f"{instruction} Write the solution in Java."
def build_prompt(task: str, user_input: str) -> str:
"""
Construct the prompt expected by the fine-tuned model.
"""
user_input = user_input.strip()
if task == "Natural Language β†’ Java":
return (
"### Instruction:\n\n"
f"{add_java_hint(user_input)}\n\n"
"### Response:\n\n"
)
return (
"### Instruction:\n\n"
"Translate the following Java code into equivalent C#. "
"Write only the C# solution.\n\n"
"### Java:\n\n"
f"{user_input}\n\n"
"### Response:\n\n"
)
# ============================================================
# GENERAL OUTPUT CLEANING
# ============================================================
def clean_output(generated_text: str) -> str:
"""
Remove Markdown fences, repeated prompt sections and
model-specific special tokens.
"""
if not generated_text:
return ""
cleaned_text = generated_text.strip()
# Extract the contents of a Markdown code block, when present.
fenced_match = re.search(
r"```(?:java|csharp|cs|c#)?\s*(.*?)```",
cleaned_text,
flags=re.DOTALL | re.IGNORECASE,
)
if fenced_match:
cleaned_text = fenced_match.group(1).strip()
# Remove prompt sections that the model may generate again.
stop_markers = [
"### Instruction:",
"### Instruction\n",
"### Java:",
"### Java\n",
"### Response:",
"### Response\n",
"<|im_start|>",
"<|im_end|>",
"<|endoftext|>",
]
for marker in stop_markers:
marker_position = cleaned_text.find(marker)
if marker_position != -1:
cleaned_text = cleaned_text[:marker_position].strip()
# Remove remaining opening or closing fences.
cleaned_text = re.sub(
r"^```(?:java|csharp|cs|c#)?\s*",
"",
cleaned_text,
flags=re.IGNORECASE,
)
cleaned_text = re.sub(
r"\s*```$",
"",
cleaned_text,
)
return cleaned_text.strip()
# ============================================================
# C# OUTPUT CLEANING
# ============================================================
def clean_csharp_output(text: str) -> str:
"""
Remove invalid virtual or override modifiers from standalone
C# method snippets.
If the output contains a class, struct, interface, record or
enum declaration, modifiers are preserved.
"""
if not text:
return ""
# Explicitly initialise code before it is accessed.
code = text.strip()
has_type_declaration = re.search(
r"\b(class|struct|interface|record|enum)\b",
code,
flags=re.IGNORECASE,
)
if has_type_declaration:
return code
# public virtual int Method() -> public int Method()
# protected override void Method() -> protected void Method()
code = re.sub(
r"\b(public|private|protected|internal)\s+"
r"(?:virtual|override)\s+",
r"\1 ",
code,
flags=re.IGNORECASE,
)
# virtual int Method() -> int Method()
# override void Method() -> void Method()
code = re.sub(
r"(^|\n)(\s*)(?:virtual|override)\s+",
r"\1\2",
code,
flags=re.IGNORECASE,
)
return code.strip()
# ============================================================
# CODE GENERATION
# ============================================================
@spaces.GPU(duration=120)
def generate_code(task: str, user_input: str) -> str:
"""
Generate Java from natural language or translate Java to C#.
"""
if not user_input or not user_input.strip():
return "Please enter a requirement or Java code."
prompt = build_prompt(task, user_input)
max_new_tokens = (
300
if task == "Natural Language β†’ Java"
else 400
)
try:
if not torch.cuda.is_available():
return "Generation failed: GPU is not available."
# Move the model to the allocated ZeroGPU device.
model.to("cuda")
model.eval()
tokenized_inputs = tokenizer(
prompt,
return_tensors="pt",
truncation=True,
max_length=2048,
)
tokenized_inputs = {
key: value.to("cuda")
for key, value in tokenized_inputs.items()
}
with torch.inference_mode():
generated_ids = model.generate(
**tokenized_inputs,
max_new_tokens=max_new_tokens,
do_sample=False,
use_cache=True,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
)
prompt_length = tokenized_inputs["input_ids"].shape[1]
new_token_ids = generated_ids[0][prompt_length:]
generated_text = tokenizer.decode(
new_token_ids,
skip_special_tokens=True,
clean_up_tokenization_spaces=False,
)
# Always run the general output cleaner.
output_code = clean_output(generated_text)
# Run the C#-specific cleaner only for Java β†’ C#.
if task == "Java β†’ C#":
output_code = clean_csharp_output(output_code)
markdown_language = "csharp"
else:
markdown_language = "java"
if not output_code:
return (
"The model returned an empty response. "
"Please try a more specific input."
)
return (
f"```{markdown_language}\n"
f"{output_code}\n"
"```"
)
except Exception as error:
return (
"Generation failed: "
f"{type(error).__name__}: {error}"
)
finally:
# Return the model to CPU after the ZeroGPU request.
try:
model.to("cpu")
except Exception as move_error:
print(f"Could not move model to CPU: {move_error}")
if torch.cuda.is_available():
torch.cuda.empty_cache()
# ============================================================
# UPDATE TEXTBOX
# ============================================================
def update_input(task: str):
"""
Update the input textbox for the selected task.
"""
if task == "Natural Language β†’ Java":
return gr.update(
label="Natural-language requirement",
placeholder=(
"Example: Write a Java method to check whether "
"a number is prime."
),
value="",
)
return gr.update(
label="Java code",
placeholder=(
"Example:\n"
"public static int factorial(int n) {\n"
" int result = 1;\n"
" for (int i = 2; i <= n; i++) {\n"
" result *= i;\n"
" }\n"
" return result;\n"
"}"
),
value="",
)
# ============================================================
# GRADIO INTERFACE
# ============================================================
with gr.Blocks(title="Java and C# CodeGen") as demo:
gr.Markdown(
"""
# Java and C# CodeGen
Generate Java code from natural-language requirements or translate Java code
into equivalent C# using a fine-tuned Qwen2.5-Coder model.
"""
)
task = gr.Dropdown(
choices=[
"Natural Language β†’ Java",
"Java β†’ C#",
],
value="Natural Language β†’ Java",
label="Select task",
)
user_input = gr.Textbox(
label="Natural-language requirement",
placeholder=(
"Example: Write a Java method to check whether "
"a number is prime."
),
lines=14,
)
generate_button = gr.Button(
"Generate Code",
variant="primary",
)
output = gr.Markdown(
value="Generated code will appear here."
)
task.change(
fn=update_input,
inputs=task,
outputs=user_input,
)
generate_button.click(
fn=generate_code,
inputs=[
task,
user_input,
],
outputs=output,
)
gr.Examples(
examples=[
[
"Natural Language β†’ Java",
(
"Write a Java method to calculate factorial "
"of a number using a loop."
),
],
[
"Natural Language β†’ Java",
"Write a Java method to reverse a string.",
],
[
"Natural Language β†’ Java",
(
"Write a Java method to check whether "
"a number is prime."
),
],
[
"Java β†’ C#",
"""public static int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}""",
],
[
"Java β†’ C#",
"""public boolean isEven(int n) {
return n % 2 == 0;
}""",
],
],
inputs=[
task,
user_input,
],
)
# ============================================================
# START APPLICATION
# ============================================================
if __name__ == "__main__":
demo.queue(
default_concurrency_limit=1,
max_size=10,
).launch()