flakeval 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ flakeval settings file: compare YOUR models or prompts on YOUR data, with proper noise estimates.
4
+
5
+ HOW TO USE
6
+ 1. Edit the settings below. Nothing else in this file needs changing (the engine lives in the flakeval package).
7
+ 2. Check your setup on a couple of rows first (no files written): python my_eval.py --dry-run
8
+ 3. Run it for real: python my_eval.py
9
+ Changed your scorer, or found it marking good answers wrong? python my_eval.py --rescore
10
+ That re-marks the saved answers without calling any model (needs SAVE_OUTPUTS = True).
11
+ A progress bar shows how far along it is (with an estimated time left). Result files go to OUT_DIR, and the
12
+ last thing printed is the verdict for each comparison.
13
+ (You got this file from `flakeval init`. Run that again in any folder to start a new evaluation.)
14
+
15
+ WHAT IT DOES
16
+ For every system in SYSTEMS it asks each question in your data RUNS times (with a different random seed each time),
17
+ scores every answer, and then uses flakeval to say whether the difference between the first system (the baseline)
18
+ and each other system is real or just noise. With RUN_A_A_TEST on, it also runs the baseline twice to show how
19
+ much two identical runs differ by chance.
20
+
21
+ PRIVACY
22
+ flakeval uploads nothing. Your rows are sent ONLY to the model endpoints you list in SYSTEMS. With a local model
23
+ (for example Ollama) nothing leaves your computer. Scores and raw model answers are written to OUT_DIR on your disk;
24
+ if your data is confidential, keep OUT_DIR out of git (add it to .gitignore).
25
+ API keys: put the key in an environment variable and name that variable in api_key_env. Never paste a key here.
26
+
27
+ COST
28
+ Total model calls = (number of questions) x RUNS x (number of systems, plus 1 for the A/A test). The script prints
29
+ this number and asks for confirmation before it starts. Try a small MAX_ITEMS first if you pay per call.
30
+ """
31
+ from flakeval.study import run_cli
32
+
33
+ # =====================================================================================================================
34
+ # EDIT THE SETTINGS BELOW
35
+ # =====================================================================================================================
36
+
37
+ # ---- Your data: a .csv (with a header row) or a .jsonl file (one JSON object per line) ----
38
+ DATA_PATH = "sample_data.csv" # relative to the folder you run this file from
39
+ INPUT_COLUMN = "question" # column with the text sent to the model
40
+ EXPECTED_COLUMN = "answer" # column with the correct answer (set to None if your SCORER does not need one)
41
+ ID_COLUMN = "id" # column with a unique id per row (set to None to just use the row number)
42
+ MAX_ITEMS = None # test on a random subset of this many rows (None = all rows). Aim for 100+ if you can.
43
+ ITEM_SEED = 0 # fixes which subset is chosen, so every system sees the same questions
44
+
45
+ # ---- How to score an answer (1 = good, 0 = bad) ----
46
+ # "exact" the answer equals the expected text (ignores case, spaces and trailing punctuation)
47
+ # "contains" the expected text appears somewhere in the answer
48
+ # "number" the LAST number in the answer equals the expected number
49
+ # "choice_letter" multiple choice: the FIRST standalone capital letter A-H in the answer is the expected letter
50
+ # "answer_line" math, strict: the number after the LAST "Answer:" in the reply equals the expected number
51
+ # "final_number" math, lenient: like answer_line, but also accepts \boxed{...} and then the last number
52
+ # "custom" your own function (see custom_score below), for anything else
53
+ SCORER = "contains"
54
+
55
+
56
+ def custom_score(output: str, expected: str, row: dict) -> float:
57
+ """Only used when SCORER = "custom". Return a number, usually 1.0 (good) or 0.0 (bad), or anything from 0 to 1.
58
+ `output` is the model's answer, `expected` is the value from EXPECTED_COLUMN, `row` is the whole data row."""
59
+ return 1.0 if output.strip() else 0.0
60
+
61
+
62
+ # ---- The systems to compare. The FIRST one is the baseline; every other one is compared against it. ----
63
+ # Two models, or the same model with two different prompts, whatever you want to compare.
64
+ # name any short label (used for file names)
65
+ # model the model name your server expects
66
+ # base_url an OpenAI-compatible endpoint. Local examples: Ollama "http://localhost:11434/v1",
67
+ # LM Studio "http://localhost:1234/v1". Hosted: see your provider's docs for its base URL.
68
+ # api_key_env NAME of the environment variable holding the API key (None for local servers)
69
+ # temperature randomness of the answers (None = do not send the setting, for models that reject it)
70
+ # system_prompt optional instructions that go before every question
71
+ # prompt_template how each question is sent; {input} is replaced by the text of INPUT_COLUMN
72
+ # Optional per system: "send_seed": False (if a provider rejects the seed setting),
73
+ # "token_limit_param": "max_completion_tokens" (needed by some newer hosted models).
74
+ SYSTEMS = [
75
+ {
76
+ "name": "model_a",
77
+ "model": "qwen2.5:3b",
78
+ "base_url": "http://localhost:11434/v1",
79
+ "api_key_env": None,
80
+ "temperature": 0.7,
81
+ "system_prompt": "",
82
+ "prompt_template": "{input}",
83
+ },
84
+ {
85
+ "name": "model_b",
86
+ "model": "llama3.2:3b",
87
+ "base_url": "http://localhost:11434/v1",
88
+ "api_key_env": None,
89
+ "temperature": 0.7,
90
+ "system_prompt": "",
91
+ "prompt_template": "{input}",
92
+ },
93
+ ]
94
+
95
+ # ---- Using something that is not an OpenAI-compatible endpoint (another SDK, a local Python model, ...)? ----
96
+ # Write a function like the one below and give it to a system with "call": my_model (instead of model/base_url).
97
+ # It receives the prompt and must return the model's answer as plain text. Example for the Anthropic Python SDK:
98
+ #
99
+ # import anthropic
100
+ # client = anthropic.Anthropic() # reads the ANTHROPIC_API_KEY environment variable
101
+ # def my_model(prompt, system_prompt, temperature, seed, max_tokens):
102
+ # msg = client.messages.create(model="your-model-name", max_tokens=max_tokens, temperature=temperature,
103
+ # system=system_prompt or anthropic.NOT_GIVEN,
104
+ # messages=[{"role": "user", "content": prompt}])
105
+ # return msg.content[0].text
106
+ # SYSTEMS[1] = {"name": "my_api_model", "call": my_model, "temperature": 0.7,
107
+ # "system_prompt": "", "prompt_template": "{input}"}
108
+ #
109
+ # (That API has no seed setting. That is fine: its answers vary on their own. Just ignore `seed`.)
110
+
111
+ # ---- How many runs and how long answers can be ----
112
+ RUNS = 5 # times each question is asked per system (3 to 5 is a good range)
113
+ MAX_TOKENS = 300 # longest answer allowed; answers cut off here are scored as they are
114
+ WORKERS = 1 # parallel requests. Raise for hosted APIs (e.g. 8); keep 1 for a single local GPU
115
+ RUN_A_A_TEST = True # also run the baseline a second time, as a sanity check on how much chance alone moves scores
116
+
117
+ # ---- Output ----
118
+ OUT_DIR = "my_results" # score files, raw answers and report.txt go here
119
+ SAVE_OUTPUTS = True # keep the raw model answers (useful for checking your scorer; may contain your data)
120
+
121
+ # =====================================================================================================================
122
+ # Nothing below needs editing.
123
+ # =====================================================================================================================
124
+ if __name__ == "__main__":
125
+ run_cli(globals()) # reads the settings above and handles --dry-run, --yes and --rescore
@@ -0,0 +1,13 @@
1
+ id,question,answer
2
+ 1,What is the capital of France? Answer in one word.,Paris
3
+ 2,What is 7 times 8? Answer with just the number.,56
4
+ 3,What is the capital of Australia? Answer in one word.,Canberra
5
+ 4,What is the chemical formula of water?,H2O
6
+ 5,How many days are there in a leap year? Answer with just the number.,366
7
+ 6,What is 12 plus 15? Answer with just the number.,27
8
+ 7,What colour do you get when you mix blue and yellow paint? Answer in one word.,green
9
+ 8,What is the largest planet in our solar system? Answer in one word.,Jupiter
10
+ 9,How many sides does a hexagon have? Answer with just the number.,6
11
+ 10,Who wrote the play Romeo and Juliet? Answer with the last name only.,Shakespeare
12
+ 11,At what temperature in degrees Celsius does water boil at sea level? Answer with just the number.,100
13
+ 12,What is the capital of Japan? Answer in one word.,Tokyo