import re import gradio as gr import spaces import torch from transformers import AutoModelForCausalLM, AutoTokenizer MODEL_ID = "shibsankardhara2/Qwen2.5-Coder-1.5B-Java-CSharp_V5" print("Loading tokenizer...") tokenizer = AutoTokenizer.from_pretrained(MODEL_ID) if tokenizer.pad_token_id is None: tokenizer.pad_token_id = tokenizer.eos_token_id print("Loading model on CPU...") model = AutoModelForCausalLM.from_pretrained( MODEL_ID, torch_dtype=torch.float16, low_cpu_mem_usage=True, ) model.eval() print("Model loaded successfully.") def add_java_hint(instruction: str) -> str: 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: 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" "Translate the following Java code into equivalent C#. " "Write the solution in C#.\n\n" "### Java\n" f"{user_input}\n\n" "### Response\n" ) def clean_output(text: str) -> str: text = text.strip() fenced = re.search( r"```(?:java|csharp|cs|c#)?\s*(.*?)```", text, flags=re.DOTALL | re.IGNORECASE, ) if fenced: text = fenced.group(1).strip() stop_markers = [ "### Instruction:", "### Instruction\n", "### Java:", "### Java\n", "### Response:", "### Response\n", "<|im_start|>", "<|im_end|>", ] for marker in stop_markers: if marker in text: text = text.split(marker, 1)[0].strip() return text @spaces.GPU(duration=120) def generate_code(task: str, user_input: str) -> str: 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: model.to("cuda") inputs = tokenizer( prompt, return_tensors="pt", truncation=True, max_length=2048, ).to("cuda") with torch.inference_mode(): outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, do_sample=False, pad_token_id=tokenizer.eos_token_id, eos_token_id=tokenizer.eos_token_id, ) generated_tokens = outputs[0][inputs["input_ids"].shape[1]:] generated_text = tokenizer.decode( generated_tokens, skip_special_tokens=True, ) code = _clean_csharp_output(generated_text) if not code: return "The model returned an empty response. Please try again." language = "java" if task == "Natural Language → Java" else "csharp" return f"```{language}\n{code}\n```" except Exception as error: return f"Generation failed: {type(error).__name__}: {error}" finally: model.to("cpu") torch.cuda.empty_cache() def update_input(task: str): 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="", ) 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() 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.", ], [ "Java → C#", """public static int factorial(int n) { int result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; }""", ], ], inputs=[ task, user_input, ], ) def _clean_csharp_output(code: str) -> str: """ Remove spurious `virtual` / `override` modifiers the model adds to bare (class-less) method snippets. The model was trained on C# methods that usually live inside a class, where `public virtual ...` is common. When it translates a *standalone* Java method it carries the `virtual` keyword over — but `virtual`/`override` are only valid on members of a class, so on a bare snippet they are invalid C#. We therefore strip them ONLY when the snippet has no enclosing type declaration (class / struct / interface / record / enum). """ if re.search(r"\b(class|struct|interface|record|enum)\b", code): return code # real type present — leave modifiers intact # Drop 'virtual'/'override' after an access modifier: 'public virtual int' -> 'public int'. code = re.sub(r"\b(public|private|protected|internal)\s+(?:virtual|override)\s+", r"\1 ", code) # Drop a leading 'virtual'/'override' with no access modifier. code = re.sub(r"(^|\n)(\s*)(?:virtual|override)\s+", r"\1\2", code) return code if __name__ == "__main__": demo.queue( default_concurrency_limit=1, max_size=10, ).launch()