pseudo2code / app.py
hamxaameer's picture
Update app.py
fffa819
raw
history blame
9.79 kB
import gradio as gr
import torch
import pickle
import io
from transformers import GPT2Tokenizer, GPT2LMHeadModel
# Load model and tokenizer from pickle files
print("Loading model and tokenizer...")
# Determine device
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using device: {device}")
try:
# Custom unpickler to handle device mapping
class CPU_Unpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == 'torch.storage' and name == '_load_from_bytes':
return lambda b: torch.load(io.BytesIO(b), map_location=device)
else:
return super().find_class(module, name)
# Load LoRA model with device mapping
print("Loading LoRA model...")
with open('gpt2_pseudo2code_lora_model.pkl', 'rb') as f:
if device == "cpu":
# Use custom unpickler for CPU
model = CPU_Unpickler(f).load()
else:
model = pickle.load(f)
print("✓ Model loaded successfully")
# Load tokenizer
print("Loading tokenizer...")
with open('gpt2_pseudo2code_tokenizer.pkl', 'rb') as f:
tokenizer = pickle.load(f)
print("✓ Tokenizer loaded successfully")
# Ensure model is on correct device
model = model.to(device)
model.eval()
print(f"✓ Model ready on {device}")
# Print model info
trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
total_params = sum(p.numel() for p in model.parameters())
print(f"✓ Total parameters: {total_params:,}")
print(f"✓ Trainable parameters: {trainable_params:,}")
except Exception as e:
print(f"Error loading model: {e}")
print("\nTrying alternative loading method...")
try:
# Alternative method: load with torch.load directly
import io
with open('gpt2_pseudo2code_lora_model.pkl', 'rb') as f:
buffer = io.BytesIO(f.read())
model = torch.load(buffer, map_location=torch.device(device))
with open('gpt2_pseudo2code_tokenizer.pkl', 'rb') as f:
tokenizer = pickle.load(f)
model = model.to(device)
model.eval()
print("✓ Model loaded successfully using alternative method")
except Exception as e2:
print(f"Alternative loading also failed: {e2}")
raise
def generate_code(pseudocode, indent, line, max_length=128, temperature=0.7, top_p=0.9):
"""
Generate code from pseudo-code with line and indent information.
Args:
pseudocode: Input pseudo-code string
indent: Indentation level
line: Line number
max_length: Maximum length of generated sequence
temperature: Sampling temperature
top_p: Nucleus sampling parameter
Returns:
Generated code string
"""
try:
# Format input with line and indent information
prompt = f"Pseudocode: {pseudocode} | Indent: {indent} | Line: {line}\nCode:"
# Tokenize input
inputs = tokenizer(prompt, return_tensors='pt', padding=True)
# Move to same device as model
device = next(model.parameters()).device
inputs = {k: v.to(device) for k, v in inputs.items()}
# Generate
model.eval()
with torch.no_grad():
outputs = model.generate(
**inputs,
max_length=max_length,
temperature=temperature,
top_p=top_p,
do_sample=True,
pad_token_id=tokenizer.eos_token_id,
eos_token_id=tokenizer.eos_token_id,
num_return_sequences=1
)
# Decode output
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
# Extract only the code part
if "Code:" in generated_text:
code = generated_text.split("Code:")[1].strip()
else:
code = generated_text.strip()
return code
except Exception as e:
return f"Error generating code: {str(e)}"
def gradio_generate_code(pseudocode, indent, line, temperature=0.7, top_p=0.9, max_length=128):
"""
Wrapper function for Gradio interface.
"""
if not pseudocode.strip():
return "⚠️ Please enter some pseudocode!"
try:
indent = int(indent)
line = int(line)
generated_code = generate_code(
pseudocode,
indent,
line,
max_length=int(max_length),
temperature=float(temperature),
top_p=float(top_p)
)
return generated_code
except ValueError:
return "⚠️ Indent and Line must be valid numbers!"
except Exception as e:
return f"❌ Error: {str(e)}"
# Example pseudocodes
examples = [
["create integer n", 1, 1, 0.7, 0.9, 128],
["read n", 1, 2, 0.7, 0.9, 128],
["for i from 0 to n", 1, 3, 0.7, 0.9, 128],
["print i", 2, 4, 0.7, 0.9, 128],
["if n is equal to 0", 1, 5, 0.7, 0.9, 128],
["create string s", 1, 1, 0.7, 0.9, 128],
["read s", 1, 2, 0.7, 0.9, 128],
]
# Create Gradio interface
with gr.Blocks(theme=gr.themes.Soft(), title="Pseudo-Code to Code Generator") as demo:
gr.Markdown(
"""
# 🐍 Pseudo-Code to Code Generator (GPT-2 + LoRA)
Convert natural language pseudo-code to executable code using a fine-tuned GPT-2 model with LoRA.
**Model Details:**
- Base Model: GPT-2
- Training: SPOC Dataset (C++ code examples)
- Optimization: LoRA (Low-Rank Adaptation) + 16-bit precision
- Trained on: 20,000 pseudo-code to code pairs
**Note:** The model was trained on C++ code examples from the SPOC dataset, so it generates C++-style code.
"""
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 📝 Input")
pseudocode_input = gr.Textbox(
label="Pseudocode",
placeholder="Enter your pseudocode here...\nExample: create integer n",
lines=5,
max_lines=10
)
with gr.Row():
indent_input = gr.Number(
label="Indent Level",
value=1,
precision=0,
info="Indentation level (0=no indent, 1=first level, etc.)"
)
line_input = gr.Number(
label="Line Number",
value=1,
precision=0,
info="Line number in the program"
)
gr.Markdown("### ⚙️ Generation Parameters")
with gr.Row():
temperature_slider = gr.Slider(
minimum=0.1,
maximum=1.5,
value=0.7,
step=0.1,
label="Temperature",
info="Higher = more creative/random"
)
top_p_slider = gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.9,
step=0.05,
label="Top-p (Nucleus Sampling)",
info="Probability threshold for sampling"
)
max_length_slider = gr.Slider(
minimum=64,
maximum=256,
value=128,
step=16,
label="Max Length",
info="Maximum tokens to generate"
)
generate_btn = gr.Button("🚀 Generate Code", variant="primary", size="lg")
with gr.Column(scale=1):
gr.Markdown("### 💻 Generated Code")
output = gr.Textbox(
label="Generated Code",
lines=15,
max_lines=20,
show_copy_button=True
)
gr.Markdown("### 📚 Examples")
gr.Examples(
examples=examples,
inputs=[pseudocode_input, indent_input, line_input, temperature_slider, top_p_slider, max_length_slider],
outputs=output,
fn=gradio_generate_code,
cache_examples=False,
)
gr.Markdown(
"""
---
### ℹ️ How to Use:
1. **Enter pseudocode**: Write your natural language description
2. **Set indent level**: Specify the indentation (0 for no indent, 1 for first level, etc.)
3. **Set line number**: Indicate the line position in your program
4. **Adjust parameters** (optional): Fine-tune temperature and top-p for different results
5. **Click Generate**: Get your code!
### 💡 Tips:
- Higher temperature (0.8-1.2) = more creative but potentially less accurate
- Lower temperature (0.5-0.7) = more conservative and predictable
- Top-p controls diversity; 0.9 is usually a good balance
- The model generates C++-style code as it was trained on the SPOC dataset
### 🔗 Resources:
- [SPOC Dataset](https://github.com/sumith1896/spoc)
- [Research Paper](https://arxiv.org/pdf/1906.04908)
- Model trained with LoRA for efficiency
"""
)
# Connect button to function
generate_btn.click(
fn=gradio_generate_code,
inputs=[pseudocode_input, indent_input, line_input, temperature_slider, top_p_slider, max_length_slider],
outputs=output
)
# Launch the app
if __name__ == "__main__":
demo.launch()