File size: 5,787 Bytes
3be3420
 
 
 
 
da14b09
3be3420
 
 
6d2324c
3be3420
 
6d2324c
3be3420
6d2324c
 
 
3be3420
 
 
 
 
 
 
 
 
 
 
 
f300f6c
 
 
 
 
 
 
 
 
 
3be3420
 
 
f300f6c
3be3420
 
f300f6c
 
3be3420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da14b09
b694338
6d2324c
 
 
 
 
 
b694338
6d2324c
 
 
 
 
 
 
 
 
3be3420
6d2324c
3be3420
 
da14b09
f300f6c
 
3be3420
 
 
b694338
3be3420
 
 
 
 
 
 
f300f6c
b694338
f300f6c
 
 
 
 
 
 
 
 
 
 
 
 
 
3be3420
 
 
 
 
b694338
 
f300f6c
 
 
 
 
b694338
3be3420
 
 
 
 
da14b09
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import random
import json
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import gradio as gr
import spaces  # Import the spaces module for ZeroGPU compatibility

# Ensure the environment has access to a CUDA-capable GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Load model and tokenizer directly to GPU if available
print("Loading tokenizer...")
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct", trust_remote_code=True)

print("Loading model...")
model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct", trust_remote_code=True, device_map="auto").to(device)

# Define templates for problems
templates = {
    "algebra": {
        "easy": ["Solve for x: {a}x + {b} = {c}", "Find the value of x: {a}x - {b} = {c}"],
        "medium": ["Solve for x: {a}x^2 + {b}x + {c} = 0", "Find the roots of: {a}x^2 - {b}x = {c}"],
        "hard": ["Solve for x: {a}x^3 + {b}x^2 + {c}x + {d} = 0", "Find the value of x in the equation: {a}x^3 - {b}x^2 + {c}x = {d}"]
    },
    "calculus": {
        "easy": ["Differentiate the function: f(x) = {a}x^2 + {b}x + {c}", "Find the derivative of: f(x) = {a}x^3 - {b}x + {c}"],
        "medium": ["Integrate the function: f(x) = {a}x^2 + {b}x + {c}", "Find the integral of: f(x) = {a}x^3 - {b}x + {c}"],
        "hard": ["Solve the differential equation: {a}dy/dx + {b}y = {c}", "Find the solution to the differential equation: {a}d^2y/dx^2 - {b}dy/dx + {c}y = 0"]
    },
    "geometry": {
        "easy": ["Find the area of a rectangle with length {a} and width {b}", "Calculate the perimeter of a rectangle with length {a} and width {b}"],
        "medium": ["Find the area of a triangle with base {a} and height {b}", "Calculate the circumference of a circle with radius {a}"],
        "hard": ["Find the volume of a cylinder with radius {a} and height {b}", "Calculate the surface area of a sphere with radius {a}"]
    },
    "trigonometry": {
        "easy": ["Find sin({a})", "Find cos({a})"],
        "medium": ["Calculate tan({a})", "Find the value of sin({a}) + cos({a})"],
        "hard": ["Solve for θ in the equation sin(θ) = {a}", "Find the angle θ for which tan(θ) = {a}"]
    }
}

def generate_synthetic_math_problems(num_problems, selected_templates):
    problems = []
    for _ in range(num_problems):
        # Randomly choose an area of mathematics from the selected templates
        area = random.choice(selected_templates)
        
        # Randomly choose a difficulty level
        difficulty = random.choice(list(templates[area].keys()))
        
        # Randomly choose a template
        template = random.choice(templates[area][difficulty])
        
        # Randomly generate parameters
        a = random.randint(1, 10)
        b = random.randint(1, 10)
        c = random.randint(1, 10)
        d = random.randint(1, 10)
        
        # Generate the problem using the template and parameters
        problem = template.format(a=a, b=b, c=c, d=d)
        problems.append(problem)
    
    return problems

@spaces.GPU(duration=60)
def solve_problem(problem, max_length):
    print(f"Solving problem: {problem}")
    with torch.no_grad():
        # Encode the problem
        inputs = tokenizer(problem, return_tensors="pt").to(device)
        
        # Generate a response from the model
        outputs = model.generate(inputs["input_ids"], max_length=max_length, num_return_sequences=1, do_sample=True)
        
        # Decode the response
        response = tokenizer.decode(outputs[0], skip_special_tokens=True)
        
        # Strip the answer to only the math (assuming answer is preceded by "The answer is ")
        if "The answer is " in response:
            answer = response.split("The answer is ")[-1].strip()
        else:
            answer = response.strip()
    
    print(f"Problem: {problem}, Answer: {answer}")
    return answer

@spaces.GPU(duration=120)
def generate_and_solve_problems(num_problems, max_length, selected_templates):
    problems = generate_synthetic_math_problems(num_problems, selected_templates)
    solved_problems = []

    for problem in problems:
        answer = solve_problem(problem, max_length)
        solved_problems.append({
            "problem": problem,
            "answer": answer
        })

    return solved_problems

def gradio_interface(num_problems, max_length, algebra, calculus, geometry, trigonometry):
    print(f"Generating and solving {num_problems} problems with max length {max_length}...")
    selected_templates = []
    if algebra:
        selected_templates.append("algebra")
    if calculus:
        selected_templates.append("calculus")
    if geometry:
        selected_templates.append("geometry")
    if trigonometry:
        selected_templates.append("trigonometry")
    
    if not selected_templates:
        return "Please select at least one math area."
    
    solved_problems = generate_and_solve_problems(num_problems, max_length, selected_templates)
    return json.dumps(solved_problems, indent=4)

# Create a Gradio interface
iface = gr.Interface(
    fn=gradio_interface,
    inputs=[
        gr.Number(label="Number of Problems", value=10, precision=0),
        gr.Slider(label="Max Output Length", minimum=10, maximum=200, value=50),
        gr.Checkbox(label="Algebra", value=True),
        gr.Checkbox(label="Calculus", value=True),
        gr.Checkbox(label="Geometry", value=True),
        gr.Checkbox(label="Trigonometry", value=True)
    ],
    outputs=gr.Textbox(label="Generated and Solved Problems"),
    title="Synthetic Math Problem Generator and Solver",
    description="Generate and solve synthetic math problems using a HuggingFace model."
)

iface.launch()