| |
| import gradio as gr |
| import pandas as pd |
| from huggingface_hub import InferenceClient |
|
|
| |
| |
| client = InferenceClient() |
|
|
| def run_evaluation(csv_file, eval_type): |
| if csv_file is None: |
| return "Please upload a CSV file first.", None |
| |
| |
| df = pd.read_csv(csv_file.name) |
| if not all(col in df.columns for col in ['prompt', 'response']): |
| return "Error: CSV must contain at least 'prompt' and 'response' columns.", None |
|
|
| results = [] |
| |
| |
| for idx, row in df.iterrows(): |
| prompt = row['prompt'] |
| response = row['response'] |
| score = 0 |
| reasoning = "" |
|
|
| if eval_type == "Basic: Length & Overlap": |
| |
| word_count = len(response.split()) |
| overlap_words = set(prompt.lower().split()) & set(response.lower().split()) |
| score = round(min(len(overlap_words) / max(len(prompt.split()), 1) * 5, 5), 1) |
| reasoning = f"Length: {word_count} words. Prompt keyword overlap: {len(overlap_words)} words." |
| |
| elif eval_type == "LLM-as-a-Judge: Correctness (Free Llama-3)": |
| |
| judge_prompt = f"""<|im_start|>system |
| You are a precise evaluation assistant. Score the response based on the prompt. |
| Output your final answer exactly in this format: |
| Score: [Your Score from 1 to 5] |
| Reasoning: [One brief sentence explaining the score] |
| <|im_end|> |
| <|im_start|>user |
| Prompt: {prompt} |
| Response: {response} |
| <|im_end|> |
| <|im_start|>assistant |
| """ |
| try: |
| |
| completion = client.text_generation( |
| prompt=judge_prompt, |
| model="Qwen/Qwen2.5-72B-Instruct", |
| max_new_tokens=150, |
| temperature=0.1 |
| ) |
| |
| |
| for line in completion.split('\n'): |
| if "Score:" in line: |
| |
| score_part = line.split("Score:")[-1].strip() |
| |
| score = float(''.join(c for c in score_part if c.isdigit() or c == '.')) |
| elif "Reasoning:" in line: |
| reasoning = line.split("Reasoning:")[-1].strip() |
| |
| except Exception as e: |
| score, reasoning = 0, f"HF API Error: {str(e)}" |
|
|
| results.append({"Score": score, "Reasoning": reasoning}) |
|
|
| |
| results_df = pd.concat([df, pd.DataFrame(results)], axis=1) |
| avg_score = results_df["Score"].mean() |
| summary_text = f"### Evaluation Complete! \n**Average Score:** {avg_score:.2f} / 5.0" |
| |
| return summary_text, results_df |
|
|
| |
| with gr.Blocks(title="Free LLM Eval MVP") as demo: |
| gr.Markdown("# 🧪 Keyless LLM Eval Engine") |
| gr.Markdown("Upload a CSV dataset with your model's outputs and evaluate them using free open-source models.") |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| file_input = gr.File(label="Upload Evaluation CSV (must have 'prompt' and 'response')", file_types=[".csv"]) |
| eval_selector = gr.Radio( |
| choices=["Basic: Length & Overlap", "LLM-as-a-Judge: Correctness (Free Llama-3)"], |
| value="Basic: Length & Overlap", |
| label="Select Evaluator" |
| ) |
| submit_btn = gr.Button("Run Evals", variant="primary") |
| |
| with gr.Column(scale=2): |
| output_summary = gr.Markdown() |
| output_table = gr.DataFrame(label="Evaluation Results") |
|
|
| submit_btn.click( |
| fn=run_evaluation, |
| inputs=[file_input, eval_selector], |
| outputs=[output_summary, output_table] |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |