Spaces:
Running
Running
File size: 4,801 Bytes
3240d27 | 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 | #evaluate_formulas.py
import re
import json
import os
from typing import List
from semantic_head import FormulaEvaluator, ExplanationLLM
# -------------------------------------------------
# 0. Preprocessing / Cleaning garbled LaTeX
# -------------------------------------------------
def clean_garbled_latex(formula: str) -> str:
formula = re.sub(r"\\underline\{\{.*?\}\}", "", formula) # remove \underline{{...}}
formula = re.sub(r"\\mit|\\bf", "", formula) # remove OCR font artifacts
formula = re.sub(r"\\l\\ell|\\L", "", formula) # remove garbled letters
formula = formula.replace(r"\rlap/", "") # remove broken \rlap/
formula = re.sub(r"[\^\_]{2,}", "", formula) # remove multiple consecutive ^ or _
formula = re.sub(r"\{\s*\}", "", formula) # remove empty braces
formula = formula.strip()
if len(formula) < 2:
return ""
return formula
# -------------------------------------------------
# 1. Extract formulas from LaTeX
# -------------------------------------------------
MATH_ENV_PATTERNS = [
r"\$(.*?)\$",
r"\\\((.*?)\\\)",
r"\\\[(.*?)\\\]",
r"\\begin\{equation\}(.*?)\\end\{equation\}",
]
def extract_formulas_from_tex(tex_content: str) -> List[str]:
formulas = []
for pattern in MATH_ENV_PATTERNS:
matches = re.findall(pattern, tex_content, re.DOTALL)
formulas.extend([m.strip() for m in matches])
return formulas
# -------------------------------------------------
# 2. Automatic minor LaTeX fixes
# -------------------------------------------------
def fix_latex(formula: str) -> str:
# Common minor fixes
formula = re.sub(r"\\backslash\s*([A-Za-z])", r"\\setminus \1", formula)
formula = formula.replace(r"\implies", r"\Rightarrow")
return formula
# -------------------------------------------------
# 3. Evaluate formulas and store results
# -------------------------------------------------
def evaluate_tex_file(tex_path: str, output_dir: str, base_model=None, lora_dir=None):
os.makedirs(output_dir, exist_ok=True)
with open(tex_path, "r", encoding="utf-8") as f:
tex_content = f.read()
formulas = extract_formulas_from_tex(tex_content)
print(f"Found {len(formulas)} formulas.")
explainer = ExplanationLLM(base_model=base_model, lora_dir=lora_dir)
evaluator = FormulaEvaluator(explainer)
results = []
for formula in formulas:
cleaned = clean_garbled_latex(formula)
if not cleaned:
print(f"Skipping garbled formula: {formula[:30]}...")
continue
fixed_formula = fix_latex(cleaned)
res = evaluator.evaluate(fixed_formula)
res_entry = {
"original_formula": formula,
"fixed_formula": fixed_formula,
**res
}
results.append(res_entry)
# Save as JSON
json_path = os.path.join(output_dir, "results_final.json")
with open(json_path, "w", encoding="utf-8") as f:
json.dump(results, f, indent=2)
# Save as TXT summary
txt_path = os.path.join(output_dir, "results_final.txt")
with open(txt_path, "w", encoding="utf-8") as f:
for r in results:
f.write(f"Original Formula: {r['original_formula']}\n")
f.write(f"Fixed Formula: {r['fixed_formula']}\n")
f.write(f"Syntactically correct: {r['syntactically_correct']}\n")
f.write(f"Mathematically correct: {r['mathematically_correct']}\n")
f.write(f"Error type: {r['error_type']}\n")
f.write(f"Confidence: {r['confidence']}\n")
f.write(f"Source: {r['source']}\n")
f.write(f"Suggested fix: {r.get('suggested_fix')}\n")
f.write(f"Explanation:\n{r['explanation']}\n")
f.write("="*80 + "\n")
print(f"Results saved to {json_path} and {txt_path}")
# -------------------------------------------------
# 4. CLI usage
# -------------------------------------------------
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Evaluate formulas in a LaTeX file with automatic minor fixes and optional LoRA model."
)
parser.add_argument("tex_file", help="Path to the LaTeX file")
parser.add_argument("--out", default="output", help="Output directory")
parser.add_argument("--base_model", default="Qwen/Qwen2.5-Math-1.5B-Instruct",
help="Base model name")
parser.add_argument("--lora_dir", default=None,
help="LoRA directory for fine-tuned model")
args = parser.parse_args()
evaluate_tex_file(
tex_path=args.tex_file,
output_dir=args.out,
base_model=args.base_model,
lora_dir=args.lora_dir
) |