Spaces:
Running
Running
File size: 2,494 Bytes
b340140 | 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 | import json
import re
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
MODEL_MAP = {
"Phi-3-mini": "microsoft/Phi-3-mini-4k-instruct",
"Mistral-7B-Instruct": "mistralai/Mistral-7B-Instruct-v0.2",
}
_pipelines = {}
def load_pipeline(model_name):
if model_name in _pipelines:
return _pipelines[model_name]
model_id = MODEL_MAP[model_name]
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="cpu",
torch_dtype="auto"
)
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_new_tokens=600,
temperature=0.5,
top_p=0.9,
do_sample=True
)
_pipelines[model_name] = pipe
return pipe
def extract_json(text):
match = re.search(r"\{[\s\S]*\}", text)
if not match:
return None
try:
return json.loads(match.group())
except:
return None
def grade_submission(
model_name,
question_paper,
rubric,
student_answer,
grading_instruction
):
pipe = load_pipeline(model_name)
understanding_prompt = f"""
Read the student submission and extract the key ideas and steps used to answer the questions.
Student Submission:
{student_answer}
Output STRICT JSON:
{{
"key_points": "concise summary of the student's approach and ideas"
}}
"""
understanding_raw = pipe(understanding_prompt)[0]["generated_text"]
understanding = extract_json(understanding_raw)
if understanding is None:
understanding = {"key_points": "Unable to reliably extract"}
grading_prompt = f"""
You are an academic autograder.
Question Paper:
{question_paper}
Rubric:
{rubric}
Grading Instruction:
{grading_instruction}
Student Key Points:
{understanding["key_points"]}
Rules:
- Follow the rubric
- Award marks for logically correct alternative solutions
- Do not penalize different notation or ordering
- Grade only what is requested
- Be fair and consistent
Output STRICT JSON ONLY:
{{
"total_marks": number,
"per_question": {{
"Q1": number,
"Q2": number
}},
"reasoning": "short justification"
}}
"""
grading_raw = pipe(grading_prompt)[0]["generated_text"]
grading = extract_json(grading_raw)
if grading is None:
return json.dumps({
"error": "Failed to generate valid grading output"
}, indent=2)
return json.dumps(grading, indent=2)
|