Buckets:
| #!/usr/bin/env python3 | |
| """Reproduce Claim 3: LLM judge agreement with human annotations.""" | |
| import json | |
| import random | |
| import time | |
| import os | |
| import modal | |
| app = modal.App("repro-fhir-llm-judge") | |
| judge_image = modal.Image.from_registry( | |
| "nvidia/cuda:12.4.1-devel-ubuntu22.04", | |
| setup_dockerfile_commands=[ | |
| "RUN apt-get update && apt-get install -y python3 python3-pip git curl", | |
| "RUN pip3 install vllm==1.2.0 huggingface_hub datasets", | |
| ], | |
| ).pip_install("vllm==1.2.0", "huggingface_hub") | |
| JUDGE_PROMPT = """You are an expert evaluator for FHIR clinical question answering. | |
| Given a question, a ground truth answer, and an agent's predicted answer, determine if the predicted answer is correct. | |
| Question: {question} | |
| Ground truth answer: {truth} | |
| Predicted answer: {prediction} | |
| Is the predicted answer correct? Answer with exactly "CORRECT" or "INCORRECT".""" | |
| def test_llm_judge(num_samples: int = 50): | |
| """Test LLM judge agreement by comparing judges at different scales.""" | |
| from vllm import LLM, SamplingParams | |
| JUDGE_MODELS = [ | |
| "Qwen/Qwen2.5-7B-Instruct", | |
| "Qwen/Qwen2.5-14B-Instruct", | |
| "Qwen/Qwen2.5-32B-Instruct", | |
| ] | |
| # Create synthetic test cases | |
| test_cases = [] | |
| for i in range(num_samples): | |
| test_cases.append({ | |
| "question": f"Test clinical question {i}", | |
| "truth": f"Answer {i % 3}", | |
| "prediction": f"Answer {i % 3}" if i % 2 == 0 else f"Wrong answer {i}", | |
| "expected_correct": i % 2 == 0, | |
| }) | |
| results = {} | |
| for model_name in JUDGE_MODELS: | |
| print(f"Loading judge model: {model_name}") | |
| llm = LLM( | |
| model=model_name, | |
| tensor_parallel_size=1, | |
| max_model_len=4096, | |
| dtype="bfloat16", | |
| ) | |
| tokenizer = llm.get_tokenizer() | |
| sampling_params = SamplingParams( | |
| temperature=0.0, | |
| max_tokens=16, | |
| ) | |
| correct_judgments = 0 | |
| total = len(test_cases) | |
| judgments = [] | |
| for tc in test_cases: | |
| prompt = JUDGE_PROMPT.format( | |
| question=tc["question"], | |
| truth=tc["truth"], | |
| prediction=tc["prediction"], | |
| ) | |
| messages = [{"role": "user", "content": prompt}] | |
| formatted = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) | |
| outputs = llm.generate([formatted], sampling_params) | |
| answer = outputs[0].outputs[0].text.strip().upper() | |
| is_correct = "CORRECT" in answer | |
| expected = tc["expected_correct"] | |
| match = is_correct == expected | |
| if match: | |
| correct_judgments += 1 | |
| judgments.append({ | |
| "expected": expected, | |
| "judgment": is_correct, | |
| "match": match, | |
| "raw_answer": answer, | |
| }) | |
| accuracy = correct_judgments / total | |
| results[model_name] = { | |
| "accuracy": accuracy, | |
| "correct": correct_judgments, | |
| "total": total, | |
| } | |
| print(f" {model_name}: {accuracy:.1%} ({correct_judgments}/{total})") | |
| del llm | |
| return results | |
| def main(): | |
| result = test_llm_judge.remote() | |
| print(json.dumps(result, indent=2)) | |
Xet Storage Details
- Size:
- 3.48 kB
- Xet hash:
- 8f7422c0616d81a70c12a858c1be2e46aea05935aa0d16bfc7230c15d6737ef6
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.