evalscope 0.17.1__py3-none-any.whl → 1.0.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.
Files changed (273) hide show
  1. evalscope/__init__.py +4 -1
  2. evalscope/api/__init__.py +0 -0
  3. evalscope/api/benchmark/__init__.py +3 -0
  4. evalscope/api/benchmark/adapters/__init__.py +3 -0
  5. evalscope/api/benchmark/adapters/default_data_adapter.py +683 -0
  6. evalscope/api/benchmark/adapters/multi_choice_adapter.py +83 -0
  7. evalscope/api/benchmark/adapters/text2image_adapter.py +155 -0
  8. evalscope/api/benchmark/benchmark.py +321 -0
  9. evalscope/api/benchmark/meta.py +115 -0
  10. evalscope/api/dataset/__init__.py +2 -0
  11. evalscope/api/dataset/dataset.py +349 -0
  12. evalscope/api/dataset/loader.py +261 -0
  13. evalscope/api/dataset/utils.py +143 -0
  14. evalscope/api/evaluator/__init__.py +3 -0
  15. evalscope/api/evaluator/cache.py +355 -0
  16. evalscope/api/evaluator/evaluator.py +56 -0
  17. evalscope/api/evaluator/state.py +264 -0
  18. evalscope/api/filter/__init__.py +1 -0
  19. evalscope/api/filter/filter.py +72 -0
  20. evalscope/api/messages/__init__.py +11 -0
  21. evalscope/api/messages/chat_message.py +198 -0
  22. evalscope/api/messages/content.py +102 -0
  23. evalscope/api/messages/utils.py +35 -0
  24. evalscope/api/metric/__init__.py +2 -0
  25. evalscope/api/metric/metric.py +55 -0
  26. evalscope/api/metric/scorer.py +105 -0
  27. evalscope/api/mixin/__init__.py +2 -0
  28. evalscope/api/mixin/dataset_mixin.py +105 -0
  29. evalscope/api/mixin/llm_judge_mixin.py +168 -0
  30. evalscope/api/model/__init__.py +12 -0
  31. evalscope/api/model/generate_config.py +157 -0
  32. evalscope/api/model/model.py +383 -0
  33. evalscope/api/model/model_output.py +285 -0
  34. evalscope/api/registry.py +182 -0
  35. evalscope/api/tool/__init__.py +3 -0
  36. evalscope/api/tool/tool_call.py +101 -0
  37. evalscope/api/tool/tool_info.py +173 -0
  38. evalscope/api/tool/utils.py +64 -0
  39. evalscope/app/ui/app_ui.py +2 -1
  40. evalscope/app/ui/multi_model.py +50 -25
  41. evalscope/app/ui/single_model.py +23 -11
  42. evalscope/app/utils/data_utils.py +42 -26
  43. evalscope/app/utils/text_utils.py +0 -2
  44. evalscope/app/utils/visualization.py +9 -4
  45. evalscope/arguments.py +6 -7
  46. evalscope/backend/opencompass/api_meta_template.py +2 -1
  47. evalscope/backend/opencompass/backend_manager.py +6 -3
  48. evalscope/backend/rag_eval/clip_benchmark/dataset_builder.py +10 -10
  49. evalscope/backend/rag_eval/clip_benchmark/task_template.py +8 -4
  50. evalscope/backend/rag_eval/ragas/task_template.py +2 -1
  51. evalscope/backend/rag_eval/ragas/tasks/build_distribution.py +2 -1
  52. evalscope/backend/rag_eval/ragas/tasks/build_transform.py +7 -4
  53. evalscope/backend/rag_eval/ragas/tasks/testset_generation.py +2 -1
  54. evalscope/backend/rag_eval/ragas/tasks/translate_prompt.py +2 -1
  55. evalscope/backend/rag_eval/utils/embedding.py +2 -1
  56. evalscope/backend/rag_eval/utils/llm.py +13 -12
  57. evalscope/benchmarks/__init__.py +0 -2
  58. evalscope/benchmarks/aigc/i2i/__init__.py +0 -0
  59. evalscope/benchmarks/aigc/i2i/general_i2i_adapter.py +44 -0
  60. evalscope/benchmarks/aigc/t2i/evalmuse_adapter.py +53 -55
  61. evalscope/benchmarks/aigc/t2i/genai_bench_adapter.py +41 -46
  62. evalscope/benchmarks/aigc/t2i/general_t2i_adapter.py +29 -45
  63. evalscope/benchmarks/aigc/t2i/hpdv2_adapter.py +34 -44
  64. evalscope/benchmarks/aigc/t2i/tifa_adapter.py +16 -27
  65. evalscope/benchmarks/aime/aime24_adapter.py +38 -40
  66. evalscope/benchmarks/aime/aime25_adapter.py +34 -40
  67. evalscope/benchmarks/alpaca_eval/alpaca_eval_adapter.py +86 -60
  68. evalscope/benchmarks/arc/arc_adapter.py +34 -147
  69. evalscope/benchmarks/arena_hard/arena_hard_adapter.py +96 -70
  70. evalscope/benchmarks/arena_hard/utils.py +37 -1
  71. evalscope/benchmarks/bbh/bbh_adapter.py +72 -144
  72. evalscope/benchmarks/bfcl/bfcl_adapter.py +181 -160
  73. evalscope/benchmarks/bfcl/generation.py +222 -0
  74. evalscope/benchmarks/ceval/ceval_adapter.py +94 -162
  75. evalscope/benchmarks/chinese_simple_qa/csimple_qa_adapter.py +85 -82
  76. evalscope/benchmarks/cmmlu/cmmlu_adapter.py +34 -125
  77. evalscope/benchmarks/competition_math/competition_math_adapter.py +56 -108
  78. evalscope/benchmarks/data_collection/data_collection_adapter.py +183 -45
  79. evalscope/benchmarks/docmath/docmath_adapter.py +109 -51
  80. evalscope/benchmarks/docmath/utils.py +4 -5
  81. evalscope/benchmarks/drop/drop_adapter.py +88 -40
  82. evalscope/benchmarks/frames/frames_adapter.py +135 -52
  83. evalscope/benchmarks/general_arena/general_arena_adapter.py +136 -98
  84. evalscope/benchmarks/general_arena/utils.py +23 -27
  85. evalscope/benchmarks/general_mcq/general_mcq_adapter.py +40 -101
  86. evalscope/benchmarks/general_qa/general_qa_adapter.py +73 -134
  87. evalscope/benchmarks/gpqa/gpqa_adapter.py +61 -100
  88. evalscope/benchmarks/gpqa/{chain_of_thought.txt → prompt.py} +12 -5
  89. evalscope/benchmarks/gsm8k/gsm8k_adapter.py +62 -142
  90. evalscope/benchmarks/hellaswag/hellaswag_adapter.py +35 -124
  91. evalscope/benchmarks/hle/hle_adapter.py +127 -93
  92. evalscope/benchmarks/humaneval/humaneval_adapter.py +86 -55
  93. evalscope/benchmarks/ifeval/ifeval_adapter.py +69 -40
  94. evalscope/benchmarks/ifeval/instructions.py +109 -64
  95. evalscope/benchmarks/ifeval/instructions_registry.py +1 -1
  96. evalscope/benchmarks/ifeval/utils.py +6 -7
  97. evalscope/benchmarks/iquiz/iquiz_adapter.py +30 -65
  98. evalscope/benchmarks/live_code_bench/evaluate_utils.py +2 -2
  99. evalscope/benchmarks/live_code_bench/live_code_bench_adapter.py +121 -71
  100. evalscope/benchmarks/live_code_bench/load_utils.py +13 -21
  101. evalscope/benchmarks/live_code_bench/testing_util.py +6 -2
  102. evalscope/benchmarks/maritime_bench/maritime_bench_adapter.py +49 -75
  103. evalscope/benchmarks/math_500/math_500_adapter.py +41 -48
  104. evalscope/benchmarks/mmlu/mmlu_adapter.py +32 -205
  105. evalscope/benchmarks/mmlu_pro/mmlu_pro_adapter.py +80 -99
  106. evalscope/benchmarks/mmlu_redux/mmlu_redux_adapter.py +64 -110
  107. evalscope/benchmarks/musr/musr_adapter.py +33 -64
  108. evalscope/benchmarks/needle_haystack/needle_haystack_adapter.py +192 -152
  109. evalscope/benchmarks/process_bench/process_bench_adapter.py +144 -76
  110. evalscope/benchmarks/race/race_adapter.py +33 -119
  111. evalscope/benchmarks/simple_qa/simple_qa_adapter.py +72 -70
  112. evalscope/benchmarks/super_gpqa/{five_shot_prompt.txt → prompt.py} +14 -16
  113. evalscope/benchmarks/super_gpqa/super_gpqa_adapter.py +73 -117
  114. evalscope/benchmarks/super_gpqa/utils.py +2 -1
  115. evalscope/benchmarks/tau_bench/generation.py +147 -0
  116. evalscope/benchmarks/tau_bench/tau_bench_adapter.py +112 -54
  117. evalscope/benchmarks/tool_bench/tool_bench_adapter.py +91 -70
  118. evalscope/benchmarks/trivia_qa/trivia_qa_adapter.py +56 -124
  119. evalscope/benchmarks/truthful_qa/truthful_qa_adapter.py +70 -265
  120. evalscope/benchmarks/winogrande/winogrande_adapter.py +28 -54
  121. evalscope/cli/cli.py +2 -0
  122. evalscope/cli/start_server.py +6 -3
  123. evalscope/collections/__init__.py +2 -10
  124. evalscope/collections/sampler.py +10 -10
  125. evalscope/collections/schema.py +13 -11
  126. evalscope/config.py +95 -54
  127. evalscope/constants.py +29 -61
  128. evalscope/evaluator/__init__.py +1 -1
  129. evalscope/evaluator/evaluator.py +277 -423
  130. evalscope/filters/__init__.py +2 -0
  131. evalscope/filters/extraction.py +126 -0
  132. evalscope/filters/selection.py +57 -0
  133. evalscope/metrics/__init__.py +13 -13
  134. evalscope/metrics/llm_judge.py +32 -30
  135. evalscope/metrics/math_parser.py +27 -22
  136. evalscope/metrics/metric.py +307 -0
  137. evalscope/metrics/metrics.py +22 -18
  138. evalscope/metrics/t2v_metrics/__init__.py +0 -52
  139. evalscope/metrics/t2v_metrics/models/clipscore_models/build_mps_model/clip_model.py +4 -2
  140. evalscope/metrics/t2v_metrics/models/clipscore_models/build_mps_model/cross_modeling.py +9 -13
  141. evalscope/metrics/t2v_metrics/models/clipscore_models/clip_model.py +2 -1
  142. evalscope/metrics/t2v_metrics/models/clipscore_models/hpsv2_model.py +3 -2
  143. evalscope/metrics/t2v_metrics/models/clipscore_models/mps_model.py +2 -1
  144. evalscope/metrics/t2v_metrics/models/clipscore_models/pickscore_model.py +2 -2
  145. evalscope/metrics/t2v_metrics/models/itmscore_models/blip2_itm_model.py +2 -1
  146. evalscope/metrics/t2v_metrics/models/itmscore_models/fga_blip2_model.py +4 -2
  147. evalscope/metrics/t2v_metrics/models/itmscore_models/image_reward/ImageReward.py +10 -5
  148. evalscope/metrics/t2v_metrics/models/itmscore_models/image_reward/blip_pretrain.py +4 -2
  149. evalscope/metrics/t2v_metrics/models/itmscore_models/image_reward_model.py +2 -1
  150. evalscope/metrics/t2v_metrics/models/vqascore_models/clip_t5/model/language_model/clip_t5.py +15 -9
  151. evalscope/metrics/t2v_metrics/models/vqascore_models/clip_t5/model/multimodal_encoder/clip_encoder.py +4 -2
  152. evalscope/metrics/t2v_metrics/models/vqascore_models/clip_t5_model.py +15 -10
  153. evalscope/metrics/t2v_metrics/models/vqascore_models/gpt4v_model.py +9 -6
  154. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/config.py +2 -2
  155. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/gradcam.py +4 -2
  156. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/logger.py +4 -2
  157. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/optims.py +3 -9
  158. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/registry.py +16 -10
  159. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/vqa_tools/vqa.py +3 -2
  160. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/common/vqa_tools/vqa_eval.py +4 -2
  161. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/__init__.py +8 -4
  162. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/Qformer.py +47 -25
  163. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/blip2_qformer.py +12 -7
  164. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/blip2_t5.py +23 -17
  165. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/blip2_t5_instruct.py +33 -23
  166. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/fga_blip2.py +2 -1
  167. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/modeling_llama.py +46 -30
  168. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip2_models/modeling_t5.py +69 -37
  169. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/__init__.py +7 -5
  170. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/blip.py +6 -4
  171. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/blip_image_text_matching.py +7 -5
  172. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/blip_nlvr.py +3 -2
  173. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/blip_outputs.py +5 -2
  174. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/blip_vqa.py +17 -13
  175. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/blip_models/nlvr_encoder.py +35 -19
  176. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/clip_vit.py +14 -12
  177. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/eva_vit.py +63 -52
  178. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/med.py +63 -38
  179. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/models/vit.py +6 -3
  180. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/processors/__init__.py +6 -2
  181. evalscope/metrics/t2v_metrics/models/vqascore_models/lavis/processors/randaugment.py +3 -2
  182. evalscope/metrics/t2v_metrics/models/vqascore_models/mm_utils.py +15 -13
  183. evalscope/metrics/t2v_metrics/models/vqascore_models/vqa_model.py +3 -2
  184. evalscope/models/__init__.py +6 -29
  185. evalscope/models/mockllm.py +65 -0
  186. evalscope/models/model_apis.py +47 -0
  187. evalscope/models/modelscope.py +455 -0
  188. evalscope/models/openai_compatible.py +123 -0
  189. evalscope/models/text2image_model.py +124 -0
  190. evalscope/models/utils/openai.py +698 -0
  191. evalscope/perf/benchmark.py +2 -1
  192. evalscope/perf/http_client.py +4 -2
  193. evalscope/perf/plugin/api/custom_api.py +5 -4
  194. evalscope/perf/plugin/api/openai_api.py +11 -9
  195. evalscope/perf/plugin/datasets/custom.py +2 -1
  196. evalscope/perf/plugin/datasets/flickr8k.py +1 -1
  197. evalscope/perf/plugin/datasets/kontext_bench.py +1 -1
  198. evalscope/perf/plugin/datasets/line_by_line.py +2 -1
  199. evalscope/perf/plugin/datasets/longalpaca.py +2 -1
  200. evalscope/perf/plugin/datasets/openqa.py +4 -2
  201. evalscope/perf/utils/benchmark_util.py +7 -5
  202. evalscope/perf/utils/db_util.py +9 -6
  203. evalscope/perf/utils/local_server.py +8 -3
  204. evalscope/perf/utils/rich_display.py +16 -10
  205. evalscope/report/__init__.py +2 -2
  206. evalscope/report/combinator.py +18 -12
  207. evalscope/report/generator.py +101 -6
  208. evalscope/report/{utils.py → report.py} +8 -6
  209. evalscope/run.py +26 -44
  210. evalscope/summarizer.py +1 -1
  211. evalscope/utils/__init__.py +21 -2
  212. evalscope/utils/chat_service.py +2 -1
  213. evalscope/utils/deprecation_utils.py +12 -1
  214. evalscope/utils/function_utils.py +29 -0
  215. evalscope/utils/io_utils.py +100 -5
  216. evalscope/utils/json_schema.py +208 -0
  217. evalscope/utils/logger.py +51 -12
  218. evalscope/utils/model_utils.py +10 -7
  219. evalscope/utils/multi_choices.py +271 -0
  220. evalscope/utils/url_utils.py +65 -0
  221. evalscope/version.py +2 -2
  222. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/METADATA +98 -49
  223. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/RECORD +234 -216
  224. tests/aigc/test_t2i.py +22 -4
  225. tests/benchmark/__init__.py +1 -0
  226. tests/benchmark/test_eval.py +386 -0
  227. tests/cli/test_all.py +3 -5
  228. tests/cli/test_collection.py +13 -4
  229. tests/cli/test_custom.py +22 -15
  230. tests/rag/test_clip_benchmark.py +1 -0
  231. evalscope/benchmarks/aigc/t2i/base.py +0 -56
  232. evalscope/benchmarks/arc/ai2_arc.py +0 -151
  233. evalscope/benchmarks/benchmark.py +0 -81
  234. evalscope/benchmarks/ceval/ceval_exam.py +0 -146
  235. evalscope/benchmarks/cmmlu/cmmlu.py +0 -161
  236. evalscope/benchmarks/cmmlu/samples.jsonl +0 -5
  237. evalscope/benchmarks/competition_math/competition_math.py +0 -79
  238. evalscope/benchmarks/data_adapter.py +0 -528
  239. evalscope/benchmarks/filters.py +0 -59
  240. evalscope/benchmarks/gsm8k/gsm8k.py +0 -121
  241. evalscope/benchmarks/hellaswag/hellaswag.py +0 -112
  242. evalscope/benchmarks/humaneval/humaneval.py +0 -79
  243. evalscope/benchmarks/mmlu/mmlu.py +0 -160
  244. evalscope/benchmarks/mmlu/samples.jsonl +0 -5
  245. evalscope/benchmarks/process_bench/critique_template.txt +0 -13
  246. evalscope/benchmarks/race/race.py +0 -104
  247. evalscope/benchmarks/race/samples.jsonl +0 -5
  248. evalscope/benchmarks/super_gpqa/zero_shot_prompt.txt +0 -4
  249. evalscope/benchmarks/trivia_qa/trivia_qa.py +0 -89
  250. evalscope/benchmarks/truthful_qa/truthful_qa.py +0 -163
  251. evalscope/benchmarks/utils.py +0 -60
  252. evalscope/collections/evaluator.py +0 -375
  253. evalscope/metrics/completion_parsers.py +0 -227
  254. evalscope/metrics/named_metrics.py +0 -55
  255. evalscope/models/adapters/__init__.py +0 -14
  256. evalscope/models/adapters/base_adapter.py +0 -84
  257. evalscope/models/adapters/bfcl_adapter.py +0 -246
  258. evalscope/models/adapters/chat_adapter.py +0 -207
  259. evalscope/models/adapters/choice_adapter.py +0 -222
  260. evalscope/models/adapters/custom_adapter.py +0 -71
  261. evalscope/models/adapters/server_adapter.py +0 -236
  262. evalscope/models/adapters/t2i_adapter.py +0 -79
  263. evalscope/models/adapters/tau_bench_adapter.py +0 -189
  264. evalscope/models/custom/__init__.py +0 -4
  265. evalscope/models/custom/custom_model.py +0 -50
  266. evalscope/models/custom/dummy_model.py +0 -99
  267. evalscope/models/local_model.py +0 -128
  268. evalscope/models/register.py +0 -41
  269. tests/cli/test_run.py +0 -489
  270. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/LICENSE +0 -0
  271. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/WHEEL +0 -0
  272. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/entry_points.txt +0 -0
  273. {evalscope-0.17.1.dist-info → evalscope-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,156 +1,76 @@
1
1
  # Copyright (c) Alibaba, Inc. and its affiliates.
2
- # Copyright (c) EleutherAI, Inc. and its affiliates.
3
- # flake8: noqa
4
- import math
5
- import os
6
- import re
7
-
8
- from evalscope.benchmarks import Benchmark, DataAdapter
9
- from evalscope.utils.io_utils import jsonl_to_list
2
+
3
+ from typing import Any, Dict
4
+
5
+ from evalscope.api.benchmark import BenchmarkMeta, DefaultDataAdapter
6
+ from evalscope.api.dataset import Sample
7
+ from evalscope.api.evaluator import TaskState
8
+ from evalscope.api.registry import register_benchmark
9
+ from evalscope.constants import Tags
10
10
  from evalscope.utils.logger import get_logger
11
11
 
12
12
  logger = get_logger()
13
13
 
14
+ PROMPT_TEMPLATE = """
15
+ Solve the following math problem step by step. The last line of your response should be of the form "ANSWER: $ANSWER" (without quotes) where $ANSWER is the answer to the problem.
16
+
17
+ {question}
18
+
19
+ Remember to put your answer on its own line at the end in the form "ANSWER: $ANSWER" (without quotes) where $ANSWER is the answer to the problem, and you do not need to use a \\boxed command.
20
+
21
+ Reasoning:
22
+ """.lstrip() # noqa: E501
23
+
24
+ FEWSHOT_TEMPLATE = """
25
+ Here are some examples of how to solve similar problems:
26
+
27
+ {fewshot}
14
28
 
15
- @Benchmark.register(
16
- name='gsm8k',
17
- pretty_name='GSM8K',
18
- tags=['Mathematics'],
19
- description=
20
- 'GSM8K (Grade School Math 8K) is a dataset of grade school math problems, designed to evaluate the mathematical reasoning abilities of AI models.',
21
- dataset_id='modelscope/gsm8k',
22
- subset_list=['main'],
23
- metric_list=['AverageAccuracy'],
24
- few_shot_num=4,
25
- train_split=None,
26
- eval_split='test',
27
- prompt_template="Question: {query}\nLet's think step by step\nAnswer:",
29
+ """.lstrip() + PROMPT_TEMPLATE
30
+
31
+
32
+ @register_benchmark(
33
+ BenchmarkMeta(
34
+ name='gsm8k',
35
+ pretty_name='GSM8K',
36
+ dataset_id='AI-ModelScope/gsm8k',
37
+ tags=[Tags.MATH, Tags.REASONING],
38
+ description=
39
+ 'GSM8K (Grade School Math 8K) is a dataset of grade school math problems, designed to evaluate the mathematical reasoning abilities of AI models.', # noqa: E501
40
+ subset_list=['main'],
41
+ few_shot_num=4,
42
+ train_split='train',
43
+ eval_split='test',
44
+ metric_list=['acc'],
45
+ prompt_template=PROMPT_TEMPLATE,
46
+ few_shot_prompt_template=FEWSHOT_TEMPLATE,
47
+ )
28
48
  )
29
- class GSM8KAdapter(DataAdapter):
49
+ class GSM8KAdapter(DefaultDataAdapter):
30
50
 
31
51
  def __init__(self, **kwargs):
32
- """
33
- Data adapter for GSM8K dataset.
34
-
35
- Args:
36
- subset_list (list): Subset list for the dataset. Default: ['main']
37
- metric_list (list): Metric list for the dataset. Default: [{'name': 'AverageAccuracy', 'object': mean}]
38
- few_shot_num (int): Number of few-shot examples. Default: 4
39
- train_split (str): Train split name. Default: 'train'
40
- eval_split (str): The target eval split name. Default: 'test'
41
- **kwargs: ...
42
- """
43
- few_shot_num = kwargs.get('few_shot_num', 4)
44
- if few_shot_num != 4 and few_shot_num != 0:
45
- logger.error(f'GSM8K uses 4-shot examples with CoT or 0-shot by system, but got {few_shot_num}. '
46
- f'Use 4-shot by default.')
47
- kwargs['few_shot_num'] = 4
48
-
49
52
  super().__init__(**kwargs)
50
53
 
51
- def load_from_disk(self, dataset_name_or_path, subset_list, work_dir, **kwargs) -> dict:
52
- data_dict = {}
53
- for subset_name in subset_list:
54
- data_dict[subset_name] = {}
55
- for split in [self.train_split, self.eval_split]:
56
- if os.path.exists(dataset_name_or_path):
57
- file_path = os.path.join(dataset_name_or_path, f'{split}.jsonl')
58
- else:
59
- file_path = os.path.join(work_dir, dataset_name_or_path, f'{split}.jsonl')
60
- if os.path.exists(file_path):
61
- data_dict[subset_name][split] = jsonl_to_list(file_path)
62
-
63
- return data_dict
64
-
65
- def gen_prompt(self, input_d: dict, few_shot_list: list, **kwargs) -> dict:
66
- """
67
- Generate prompt for the model.
68
-
69
- Args:
70
- input_d (dict): The raw input. A single data format of the GSM8K:
71
- {
72
- "question": "Janet\\u2019s ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her friends every day with four. She sells the remainder at the farmers\' market daily for $2 per fresh duck egg. How much in dollars does she make every day at the farmers\' market?",
73
- "answer": "Janet sells 16 - 3 - 4 = <<16-3-4=9>>9 duck eggs a day.\\nShe makes 9 * 2 = $<<9*2=18>>18 every day at the farmer\\u2019s market.\\n#### 18"
74
- }
75
- """
76
- use_fewshot = self.few_shot_num > 0
77
- context = self._generate_prompt(use_fewshot=use_fewshot)
78
-
79
- full_prompt = context + self.prompt_template.format(query=input_d['question'])
80
-
81
- return self.gen_prompt_data(full_prompt)
82
-
83
- def get_gold_answer(self, input_d: dict) -> str:
84
- # Extract the gold answer from the input dict.
85
- ans: str = input_d.get('answer', '')
86
- ans = self.extract_answer(ans).strip()
87
- if not ans:
88
- logger.error(f'No ground truth answer found in the input: {input_d}')
89
- return ans
90
-
91
- def parse_pred_result(self, result: str, raw_input_d: dict = None, eval_type: str = 'checkpoint') -> str:
92
- """
93
- Parse the model output to get the answer. Could be the best choice index.
94
-
95
- Args:
96
- result: Predicted answer from the model. Usually a string for chat.
97
- raw_input_d (dict): The raw input. Depending on the dataset.
98
- eval_type (str): 'checkpoint' or 'service'
99
-
100
- Returns:
101
- The parsed answer. Depending on the dataset. Usually a string for chat.
102
- """
103
- # Note: to use same extraction method for both of checkpoint and custom.
104
- return self.extract_answer(result)
105
-
106
- def match(self, gold: str, pred: str) -> float:
107
- """
108
- Match the gold answer and predicted answer.
109
-
110
- Args:
111
- gold (str): The golden answer. Note: to be extracted.
112
- pred (str): The extracted prediction. Usually a string for chat/multiple-choice-questions.
113
- e.g. 'B'
114
- """
115
-
116
- def number_equal(gold_ans, pred_ans):
117
- if pred_ans is None:
118
- return False
119
- try:
120
- return math.isclose(eval(gold_ans), eval(pred_ans), rel_tol=0, abs_tol=1e-4)
121
- except:
122
- logger.warning(f'##report##Cannot compare two numbers: gold_ans={gold_ans}, pred_ans={pred_ans}')
123
- return False
124
-
125
- return number_equal(gold_ans=gold, pred_ans=pred)
126
-
127
- @classmethod
128
- def _generate_prompt(cls, use_fewshot: bool = True) -> str:
129
- if use_fewshot:
130
- # Use 4-shot examples by system
131
- context = (
132
- "Question: Angelo and Melanie want to plan how many hours over the next week they should study together for their test next week. They have 2 chapters of their textbook to study and 4 worksheets to memorize. They figure out that they should dedicate 3 hours to each chapter of their textbook and 1.5 hours for each worksheet. If they plan to study no more than 4 hours each day, how many days should they plan to study total over the next week if they take a 10-minute break every hour, include 3 10-minute snack breaks each day, and 30 minutes for lunch each day?\nLet's think step by step\n"
133
- 'Angelo and Melanie think they should dedicate 3 hours to each of the 2 chapters, 3 hours x 2 chapters = 6 hours total.\nFor the worksheets they plan to dedicate 1.5 hours for each worksheet, 1.5 hours x 4 worksheets = 6 hours total.\nAngelo and Melanie need to start with planning 12 hours to study, at 4 hours a day, 12 / 4 = 3 days.\nHowever, they need to include time for breaks and lunch. Every hour they want to include a 10-minute break, so 12 total hours x 10 minutes = 120 extra minutes for breaks.\nThey also want to include 3 10-minute snack breaks, 3 x 10 minutes = 30 minutes.\nAnd they want to include 30 minutes for lunch each day, so 120 minutes for breaks + 30 minutes for snack breaks + 30 minutes for lunch = 180 minutes, or 180 / 60 minutes per hour = 3 extra hours.\nSo Angelo and Melanie want to plan 12 hours to study + 3 hours of breaks = 15 hours total.\nThey want to study no more than 4 hours each day, 15 hours / 4 hours each day = 3.75\nThey will need to plan to study 4 days to allow for all the time they need.\nThe answer is 4\n\n'
134
- "Question: Mark's basketball team scores 25 2 pointers, 8 3 pointers and 10 free throws. Their opponents score double the 2 pointers but half the 3 pointers and free throws. What's the total number of points scored by both teams added together?\nLet's think step by step\n"
135
- "Mark's team scores 25 2 pointers, meaning they scored 25*2= 50 points in 2 pointers.\nHis team also scores 6 3 pointers, meaning they scored 8*3= 24 points in 3 pointers\nThey scored 10 free throws, and free throws count as one point so they scored 10*1=10 points in free throws.\nAll together his team scored 50+24+10= 84 points\nMark's opponents scored double his team's number of 2 pointers, meaning they scored 50*2=100 points in 2 pointers.\nHis opponents scored half his team's number of 3 pointers, meaning they scored 24/2= 12 points in 3 pointers.\nThey also scored half Mark's team's points in free throws, meaning they scored 10/2=5 points in free throws.\nAll together Mark's opponents scored 100+12+5=117 points\nThe total score for the game is both team's scores added together, so it is 84+117=201 points\nThe answer is 201\n\n"
136
- "Question: Bella has two times as many marbles as frisbees. She also has 20 more frisbees than deck cards. If she buys 2/5 times more of each item, what would be the total number of the items she will have if she currently has 60 marbles?\nLet's think step by step\n"
137
- "When Bella buys 2/5 times more marbles, she'll have increased the number of marbles by 2/5*60 = 24\nThe total number of marbles she'll have is 60+24 = 84\nIf Bella currently has 60 marbles, and she has two times as many marbles as frisbees, she has 60/2 = 30 frisbees.\nIf Bella buys 2/5 times more frisbees, she'll have 2/5*30 = 12 more frisbees.\nThe total number of frisbees she'll have will increase to 30+12 = 42\nBella also has 20 more frisbees than deck cards, meaning she has 30-20 = 10 deck cards\nIf she buys 2/5 times more deck cards, she'll have 2/5*10 = 4 more deck cards.\nThe total number of deck cards she'll have is 10+4 = 14\nTogether, Bella will have a total of 14+42+84 = 140 items\nThe answer is 140\n\n"
138
- "Question: A group of 4 fruit baskets contains 9 apples, 15 oranges, and 14 bananas in the first three baskets and 2 less of each fruit in the fourth basket. How many fruits are there?\nLet's think step by step\n"
139
- 'For the first three baskets, the number of apples and oranges in one basket is 9+15=24\nIn total, together with bananas, the number of fruits in one basket is 24+14=38 for the first three baskets.\nSince there are three baskets each having 38 fruits, there are 3*38=114 fruits in the first three baskets.\nThe number of apples in the fourth basket is 9-2=7\nThere are also 15-2=13 oranges in the fourth basket\nThe combined number of oranges and apples in the fourth basket is 13+7=20\nThe fourth basket also contains 14-2=12 bananas.\nIn total, the fourth basket has 20+12=32 fruits.\nThe four baskets together have 32+114=146 fruits.\nThe answer is 146\n\n'
54
+ def record_to_sample(self, record: Dict[str, Any]) -> Sample:
55
+ DELIM = '####'
56
+ question = record['question']
57
+ answer = record['answer'].split(DELIM)
58
+ target = answer.pop().strip()
59
+ reasoning = DELIM.join(answer)
60
+
61
+ return Sample(input=question, target=target, metadata={'reasoning': reasoning.strip()})
62
+
63
+ def sample_to_fewshot(self, sample: Sample) -> str:
64
+ if sample.metadata:
65
+ return (
66
+ f'{sample.input}\n\nReasoning:\n' + f"{sample.metadata['reasoning']}\n\n" + f'ANSWER: {sample.target}'
140
67
  )
141
68
  else:
142
- context = ''
143
- return context
144
-
145
- @staticmethod
146
- def extract_answer(s: str) -> str:
147
- _PAT_LAST_DIGIT = re.compile(r'([+-])?(?=([0-9]|\.[0-9]))(0|([1-9](\d{0,2}(,\d{3})*)|\d*))?(\.\d*)?(?=\D|$)')
148
- match = list(_PAT_LAST_DIGIT.finditer(s))
149
- if match:
150
- last_digit = match[-1].group().replace(',', '').replace('+', '').strip().strip('.')
151
- # print(f"The last digit in {s} is {last_digit}")
152
- else:
153
- last_digit = None
154
- print(f'No digits found in {s!r}', flush=True)
69
+ return ''
70
+
71
+ def extract_answer(self, prediction: str, task_state: TaskState):
72
+ from evalscope.filters.extraction import RegexFilter
155
73
 
156
- return last_digit
74
+ regex = RegexFilter(regex_pattern=r'(-?[0-9.,]{2,})|(-?[0-9]+)', group_select=-1)
75
+ res = regex(prediction)
76
+ return res.replace(',', '').replace('+', '').strip().strip('.')
@@ -3,118 +3,56 @@ import numpy as np
3
3
  import os
4
4
  import re
5
5
 
6
- from evalscope.benchmarks import Benchmark, DataAdapter
7
- from evalscope.constants import EvalType, OutputType
8
- from evalscope.metrics import exact_match
9
- from evalscope.metrics.completion_parsers import ResponseParser
10
- from evalscope.utils.io_utils import jsonl_to_list
6
+ from evalscope.api.benchmark import BenchmarkMeta, MultiChoiceAdapter
7
+ from evalscope.api.dataset import Sample
8
+ from evalscope.api.registry import register_benchmark
9
+ from evalscope.constants import Tags
11
10
  from evalscope.utils.logger import get_logger
11
+ from evalscope.utils.multi_choices import MultipleChoiceTemplate
12
12
 
13
13
  # flake8: noqa
14
14
 
15
15
  logger = get_logger()
16
16
 
17
17
 
18
- @Benchmark.register(
19
- name='hellaswag',
20
- pretty_name='HellaSwag',
21
- tags=['Commonsense', 'MCQ', 'Knowledge'],
22
- description=
23
- 'HellaSwag is a benchmark for commonsense reasoning in natural language understanding tasks. It consists of multiple-choice questions where the model must select the most plausible continuation of a given context.',
24
- dataset_id='modelscope/hellaswag',
25
- model_adapter=OutputType.MULTIPLE_CHOICE,
26
- output_types=[OutputType.MULTIPLE_CHOICE, OutputType.GENERATION],
27
- subset_list=['default'],
28
- metric_list=['AverageAccuracy'],
29
- few_shot_num=0,
30
- train_split='train',
31
- eval_split='validation',
32
- prompt_template='{query}', # noqa: E501
18
+ @register_benchmark(
19
+ BenchmarkMeta(
20
+ name='hellaswag',
21
+ pretty_name='HellaSwag',
22
+ tags=[Tags.COMMONSENSE, Tags.MULTIPLE_CHOICE, Tags.KNOWLEDGE],
23
+ description=
24
+ 'HellaSwag is a benchmark for commonsense reasoning in natural language understanding tasks. It consists of multiple-choice questions where the model must select the most plausible continuation of a given context.',
25
+ dataset_id='evalscope/hellaswag',
26
+ metric_list=['acc'],
27
+ subset_list=['default'],
28
+ few_shot_num=0,
29
+ train_split=None,
30
+ eval_split='validation',
31
+ prompt_template=MultipleChoiceTemplate.SINGLE_ANSWER,
32
+ )
33
33
  )
34
- class HellaSwagAdapter(DataAdapter):
34
+ class HellaSwagAdapter(MultiChoiceAdapter):
35
35
 
36
36
  def __init__(self, **kwargs):
37
-
38
- few_shot_num = kwargs.get('few_shot_num', 0)
39
- if few_shot_num != 0:
40
- logger.warning(f'few_shot_num should be 0 for HellaSwag, but got {few_shot_num}. Use 0-shot by default.')
41
- kwargs['few_shot_num'] = 0
42
-
43
37
  super().__init__(**kwargs)
44
- self.choices = ['A', 'B', 'C', 'D']
45
-
46
- def load_from_disk(self, dataset_name_or_path, subset_list, work_dir, **kwargs) -> dict:
47
- data_dict = {}
48
- for subset_name in subset_list:
49
- data_dict[subset_name] = {}
50
- for split in [self.train_split, self.eval_split]:
51
- if os.path.exists(dataset_name_or_path):
52
- file_path = os.path.join(dataset_name_or_path, f'hellaswag_{split}.jsonl')
53
- else:
54
- file_path = os.path.join(work_dir, dataset_name_or_path, f'hellaswag_{split}.jsonl')
55
- if os.path.exists(file_path):
56
- data_dict[subset_name][split] = jsonl_to_list(file_path)
57
-
58
- return data_dict
59
-
60
- def gen_prompt(self, input_d: dict, few_shot_list: list, **kwargs) -> dict:
61
- """
62
- Generate model prompt from raw data, unify the prompt format for HellaSwag benchmark.
63
-
64
- Args:
65
- input_d (dict): The raw input. A single data format of the HellaSwag:
66
-
67
- {
68
- 'ind': 4,
69
- 'activity_label': 'Removing ice from car',
70
- 'ctx_a': 'Then, the man writes over the snow covering the window of a car, and a woman wearing winter clothes smiles.',
71
- 'ctx_b': 'then',
72
- 'ctx': 'Then, the man writes over the snow covering the window of a car, and a woman wearing winter clothes smiles. then',
73
- 'endings': [', the man adds wax to the windshield and cuts it.', ', a person board a ski lift, while two men supporting the head of the person wearing winter clothes snow as the we girls sled.', ', the man puts on a christmas coat, knitted with netting.', ', the man continues removing the snow on his car.'],
74
- 'source_id': 'activitynet~v_-1IBHYS3L-Y',
75
- 'split': 'train',
76
- 'split_type': 'indomain',
77
- 'label': '3'
78
- }
79
-
80
- Returns:
81
- Refer to function: evalscope.benchmarks.data_adapter.DataAdapter.gen_prompt for details.
82
- """
83
-
84
- endings: list = [self._preprocess(ending) for ending in input_d['endings']]
85
-
86
- few_shot_prompts = [
87
- self._generate_prompt(input_d=sample, endings=endings, include_answer=True) for sample in few_shot_list
88
- ]
89
- context: str = '\n'.join(few_shot_prompts) + '\n'
90
- query = context.strip() + self._generate_prompt(input_d=input_d, endings=endings, include_answer=False)
91
38
 
92
- full_prompt = self.prompt_template.format(query=query)
93
- return self.gen_prompt_data(full_prompt)
39
+ def record_to_sample(self, record) -> Sample:
40
+ # Preprocess endings
41
+ endings = [self._preprocess(ending) for ending in record['endings']]
94
42
 
95
- def get_gold_answer(self, input_d: dict) -> str:
96
- # Get the gold choice from the label
97
- return self.choices[int(input_d['label'])]
43
+ # Create context
44
+ ctx = record['ctx_a'] + ' ' + record['ctx_b'].capitalize()
45
+ context = self._preprocess(ctx)
98
46
 
99
- def parse_pred_result(self, result: list, raw_input_d: dict = None, eval_type: str = EvalType.CHECKPOINT) -> str:
100
- """
101
- Parse the model output to get the answer. Could be the best choice index.
47
+ # Get target choice letter
48
+ target_letter = ['A', 'B', 'C', 'D'][int(record['label'])]
102
49
 
103
- Args:
104
- result: Predicted answer from the model. Usually a string for chat.
105
- raw_input_d: The raw input dict.
106
- eval_type: The evaluation type. e.g. checkpoint, service, custom.
107
-
108
- Returns:
109
- The parsed answer. Depending on the dataset. Usually a string for chat.
110
- """
111
- if self.model_adapter == OutputType.MULTIPLE_CHOICE:
112
- return result
113
- else:
114
- return ResponseParser.parse_first_option(result, options=self.choices)
115
-
116
- def match(self, gold: str, pred: str) -> float:
117
- return exact_match(gold=str(gold), pred=str(pred))
50
+ return Sample(
51
+ input=context,
52
+ choices=endings,
53
+ target=target_letter,
54
+ metadata={'activity_label': record.get('activity_label', 'unknown')},
55
+ )
118
56
 
119
57
  def _preprocess(self, text):
120
58
  text = text.strip()
@@ -122,30 +60,3 @@ class HellaSwagAdapter(DataAdapter):
122
60
  text = re.sub('\\[.*?\\]', '', text)
123
61
  text = text.replace(' ', ' ')
124
62
  return text
125
-
126
- def _generate_prompt(self, input_d: dict, endings: list, include_answer=True) -> str:
127
- """
128
- Generate prompt for HellaSwag dataset.
129
-
130
- Args:
131
- input_d: a single data of the hellaswag.
132
- endings: preprocessed endings
133
- include_answer: bool
134
-
135
- Returns:
136
-
137
- """
138
-
139
- ctx = input_d['ctx_a'] + ' ' + input_d['ctx_b'].capitalize()
140
- # example: str = cls._preprocess(input_d['activity_label'] + ': ' + ctx)
141
- example: str = self._preprocess(ctx)
142
-
143
- example += '\nQuestion: Which ending makes the most sense?'
144
- for i, ending in enumerate(endings):
145
- example += f'\n{self.choices[i]}. {ending}'
146
- example += '\nYou may choose from A, B, C, D. Derive your final answer as `The answer is ...`.'
147
-
148
- if include_answer:
149
- example += '{}\n\n'.format(endings[int(input_d['label'])])
150
-
151
- return example
@@ -1,9 +1,13 @@
1
1
  import re
2
- from collections import defaultdict
3
- from typing import Any, List
4
-
5
- from evalscope.benchmarks import Benchmark, DataAdapter
6
- from evalscope.metrics import DEFAULT_PROMPT_TEMPLATE, LLMJudge, exact_match, mean
2
+ from typing import Any, Dict, List
3
+
4
+ from evalscope.api.benchmark import BenchmarkMeta, DefaultDataAdapter
5
+ from evalscope.api.dataset import Sample
6
+ from evalscope.api.evaluator import TaskState
7
+ from evalscope.api.messages import ChatMessage, ChatMessageSystem, ChatMessageUser, Content, ContentImage, ContentText
8
+ from evalscope.api.metric import Score
9
+ from evalscope.api.registry import register_benchmark
10
+ from evalscope.constants import Tags
7
11
  from evalscope.utils.logger import get_logger
8
12
 
9
13
  # flake8: noqa
@@ -21,98 +25,128 @@ SUBSET_LIST = [
21
25
  'Other',
22
26
  ]
23
27
 
28
+ ANSWER_TYPE_EXACT_MATCH = 'exactMatch'
29
+ ANSWER_TYPE_MULTIPLE_CHOICE = 'multipleChoice'
30
+
31
+ # System prompt constants
32
+ SYSTEM_EXACT_ANSWER = 'Your response should be in the following format:\nExplanation: {your explanation for your final answer}\nExact Answer: {your succinct, final answer}\nConfidence: {your confidence score between 0% and 100% for your answer}'
33
+
34
+ SYSTEM_MC = 'Your response should be in the following format:\nExplanation: {your explanation for your answer choice}\nAnswer: {your chosen answer}\nConfidence: {your confidence score between 0% and 100% for your answer}'
35
+
36
+ JUDGE_PROMPT = """Judge whether the following [response] to [question] is correct or not based on the precise and unambiguous [correct_answer] below.
37
+
38
+ [question]: {question}
39
+
40
+ [response]: {response}
41
+
42
+ [correct_answer]: {correct_answer}
24
43
 
25
- @Benchmark.register(
26
- name='hle',
27
- pretty_name="Humanity's-Last-Exam",
28
- tags=['Knowledge', 'QA'],
29
- description=
30
- 'Humanity\'s Last Exam (HLE) is a language model benchmark consisting of 2,500 questions across a broad range of subjects. It was created jointly by the Center for AI Safety and Scale AI. The benchmark classifies the questions into the following broad subjects: mathematics (41%), physics (9%), biology/medicine (11%), humanities/social science (9%), computer science/artificial intelligence (10%), engineering (4%), chemistry (7%), and other (9%). Around 14% of the questions require the ability to understand both text and images, i.e., multi-modality. 24% of the questions are multiple-choice; the rest are short-answer, exact-match questions.', # noqa: E501
31
- dataset_id='cais/hle',
32
- subset_list=SUBSET_LIST,
33
- metric_list=['AverageAccuracy'],
34
- few_shot_num=0,
35
- train_split=None,
36
- eval_split='test',
37
- prompt_template='{query}\n\nPlease reason step by step, and put your final answer within \\boxed{{}}.',
44
+ Your judgment must focus only on if there are meaningful differences between [correct_answer] and the [response]. Do not comment on any background to the problem, do not attempt to solve the problem, do not argue for any answer different than [correct_answer], focus only on whether the answers match. Explain why the [response] is correct or incorrect based on [correct_answer] in one or two sentences. Finally, write your answer in the format 'GRADE: C' for correct answer or 'GRADE: I' for incorrect answer.
45
+ """
46
+
47
+
48
+ @register_benchmark(
49
+ BenchmarkMeta(
50
+ name='hle',
51
+ pretty_name="Humanity's-Last-Exam",
52
+ tags=[Tags.KNOWLEDGE, Tags.QA],
53
+ description='Humanity\'s Last Exam (HLE) is a language model benchmark consisting of 2,500 '
54
+ 'questions across a broad range of subjects. It was created jointly by the Center '
55
+ 'for AI Safety and Scale AI. The benchmark classifies the questions into the '
56
+ 'following broad subjects: mathematics (41%), physics (9%), biology/medicine (11%), '
57
+ 'humanities/social science (9%), computer science/artificial intelligence (10%), '
58
+ 'engineering (4%), chemistry (7%), and other (9%). Around 14% of the questions '
59
+ 'require the ability to understand both text and images, i.e., multi-modality. '
60
+ '24% of the questions are multiple-choice; the rest are short-answer, exact-match questions. '
61
+ 'To evaluate the performance of model without multi-modality capabilities, please set the extra_params["include_multi_modal"] to False.', # noqa: E501
62
+ dataset_id='cais/hle',
63
+ subset_list=SUBSET_LIST,
64
+ metric_list=['acc'],
65
+ eval_split='test',
66
+ prompt_template='{question}',
67
+ extra_params={'include_multi_modal': True}
68
+ )
38
69
  )
39
- class HLEAdapter(DataAdapter):
70
+ class HLEAdapter(DefaultDataAdapter):
40
71
 
41
72
  def __init__(self, *args, **kwargs):
42
73
  super().__init__(*args, **kwargs)
43
74
 
44
- self.llm_as_a_judge = True
45
-
46
- def load(self, **kwargs):
47
- kwargs['subset_list'] = ['default']
48
- data_dict = super().load(**kwargs)
49
- return self.reformat_subset(data_dict, subset_key='category', format='{}')
50
-
51
- def gen_prompt(self, input_d: dict, subset_name: str, few_shot_list: list, **kwargs) -> dict:
52
- # remove image preview
53
- input_d.pop('image_preview', None)
54
- input_d.pop('rationale_image', None)
55
- # generate prompt
56
- question = input_d['question']
57
- prompt = self.prompt_template.format(query=question)
58
- image = input_d.get('image', None)
59
- # build messages for multi-modal input
60
- messages = []
61
- if self.system_prompt:
62
- messages.append({'role': 'system', 'content': self.system_prompt})
63
- if image:
64
- messages.append({
65
- 'role':
66
- 'user',
67
- 'content': [{
68
- 'type': 'text',
69
- 'text': prompt
70
- }, {
71
- 'type': 'image_url',
72
- 'image_url': {
73
- 'url': image
74
- }
75
- }]
76
- })
77
- else:
78
- messages.append({'role': 'user', 'content': prompt})
79
- return self.gen_prompt_data(prompt='', messages=messages)
80
-
81
- def get_gold_answer(self, input_d: dict) -> str:
82
- return input_d['answer']
83
-
84
- def parse_pred_result(self, result: str, raw_input_d: dict = None, **kwargs) -> str:
85
- # Extract the answer from the model output \boxed{answer}
86
- match = re.search(r'\\boxed{([^}]*)}', result)
87
- if match:
88
- return match.group(1).strip()
89
- else:
90
- logger.warning(f'No answer found in the model output: {result}')
91
- return ''
92
-
93
- def llm_parse_pred_result(self, result, raw_input_d=None, **kwargs) -> str:
94
- return result.strip()
95
-
96
- def match(self, gold: str, pred: str) -> dict:
97
- # simple match
98
- return {
99
- 'AverageAccuracy': 1.0 if exact_match(gold, pred) else 0.0,
100
- }
101
-
102
- def llm_match(self, gold: Any, pred: Any, judge: LLMJudge, **kwargs) -> dict:
103
- raw_input = kwargs.get('raw_input', None)
104
- question = raw_input['question']
105
- # get grading response
106
- prompt = judge.build_prompt(pred, gold, question)
107
- judge_response = judge(prompt)
108
- score = judge.get_score(judge_response)
109
- return {
110
- 'AverageAccuracy': score,
111
- 'response': judge_response,
75
+ self._use_llm_judge = True # Use LLM as a judge by default
76
+ self.reformat_subset = True
77
+ self.include_multi_modal = self.extra_params.get('include_multi_modal', True)
78
+
79
+ def record_to_sample(self, record: Dict[str, Any]) -> Sample:
80
+ answer_type = record['answer_type']
81
+ system_prompt = (SYSTEM_EXACT_ANSWER if answer_type == ANSWER_TYPE_EXACT_MATCH else SYSTEM_MC)
82
+ text_content = ContentText(text=record['question'])
83
+
84
+ content: List[Content] = [text_content]
85
+ if record['image']:
86
+ image_content = ContentImage(image=record['image'])
87
+ content.append(image_content)
88
+
89
+ messages: List[ChatMessage] = [
90
+ ChatMessageSystem(content=system_prompt),
91
+ ChatMessageUser(content=content),
92
+ ]
93
+ return Sample(
94
+ input=messages,
95
+ subset_key=record['category'],
96
+ metadata={
97
+ 'uid': record['id'],
98
+ 'author_name': record['author_name'],
99
+ 'rationale': record['rationale'],
100
+ 'raw_subject': record['raw_subject'],
101
+ 'category': record['category'],
102
+ 'has_image': bool(record['image']),
103
+ },
104
+ target=record['answer'],
105
+ )
106
+
107
+ def sample_filter(self, sample):
108
+ if not self.include_multi_modal:
109
+ if sample.metadata is not None and sample.metadata['has_image']:
110
+ return False
111
+ return True
112
+
113
+ def llm_match_score(
114
+ self,
115
+ original_prediction: str,
116
+ filtered_prediction: str,
117
+ reference: str,
118
+ task_state: TaskState,
119
+ ) -> Score:
120
+ score = Score(
121
+ extracted_prediction=filtered_prediction,
122
+ prediction=original_prediction,
123
+ )
124
+
125
+ confidence = 100
126
+ if task_state.output and task_state.output.completion:
127
+ confidence_match = re.search(r'confidence:\s*(\d+)', task_state.output.completion, re.IGNORECASE)
128
+ if confidence_match:
129
+ confidence = int(confidence_match.group(1))
130
+
131
+ judge_prompt = JUDGE_PROMPT.format(
132
+ question=task_state.input_text, response=filtered_prediction, correct_answer=reference
133
+ )
134
+
135
+ # Request judge and obtain score
136
+ judge_response = self.llm_judge.judge(prompt=judge_prompt)
137
+
138
+ # Parse judge response to get accuracy score
139
+ accuracy_score = re.search(r'GRADE:\s*([CI])', judge_response, re.IGNORECASE)
140
+ if accuracy_score:
141
+ score.value = {
142
+ 'acc': 1.0 if accuracy_score.group(1) == 'C' else 0.0,
143
+ }
144
+ score.explanation = f'LLM judge: {judge_response}'
145
+ score.metadata = {
146
+ 'source': 'llm_judge',
147
+ 'judge_strategy': self.judge_strategy,
148
+ 'model': self.llm_judge.model_id,
149
+ 'confidence': confidence,
112
150
  }
113
-
114
- def compute_metric(self, review_res_list: List[dict], **kwargs) -> List[dict]:
115
- # zip dict answers
116
- res_dict = super().compute_dict_metric(review_res_list, **kwargs)
117
-
118
- return super().compute_metric(res_dict, **kwargs)
151
+ score.main_score_name = 'acc'
152
+ return score