MMLU and MMLU Pro

Source

MMLU和MMLU-Pro的比較

特徵 MMLU MMLU-Pro
範圍和內容 包含各種領域的廣泛問題集,主要以知識為主。評估模型的記憶和理解能力。 在MMLU的基礎上添加了更複雜的推理問題。重點在於評估高階認知技能,如問題解決和批判性思維。
難度等級 包含混合難度的問題,其中一些相對簡單或瑣碎。 通過去除簡單和噪聲問題並整合需要更深層推理的問題,顯著提高了挑戰性。
選項數量 每個問題提供四個選項。 選項擴展到十個,增加了難度,減少了隨機猜對的可能性。
準確性和敏感性 當前模型已達到高準確度,導致性能趨於平緩,對提示變化敏感(4-5%敏感性)。 由於難度增加,準確率顯著下降(比MMLU低16%到33%)。對提示變化的敏感性減少到僅2%,顯示出更大的穩定性和穩健性。
推理與直接回答 模型通常在直接回答技術上表現良好。 使用鏈式思考(CoT)推理的模型表現優於直接回答的模型,強調數據集對複雜推理任務的關注。

Introduction

大模型(LLM)的评测是衡量大模型效果的关键步骤,也是模型流水线中必不可少的过程。常见的大模型排行榜或平台有🤗 Open LLM LeaderboardOpenCompassChatbot Arena Leaderboard.

那么,大模型的评测是如何实现的呢?

本文将会以MMLU数据集为例,考察主流开源大模型,如LLAMA-2, BaiChuan-2等模型的评估实现及结果,希望能管中规豹,一探究竟。

NLP(七十八)大模型探索:MMLU数据集评测 - My Github Blog (percent4.github.io)

MMLU Pro 数据集

隨著模型的持續改進,它們在 MMLU 測試上的表現開始趨於平緩,使得分辨模型能力的差異變得越來越困難。本文介紹了MMLU-Pro,一個增強的數據集,旨在通過引入更具挑戰性的推理問題和將選項從四個擴展到十個,來擴展以知識為主的MMLU基準。此外,MMLU-Pro消除了MMLU中瑣碎和噪聲問題。我們的實驗結果表明,與MMLU相比,MMLU-Pro不僅提高了挑戰性,導致準確率顯著下降16%到33%,而且在不同提示下顯示出更大的穩定性。測試了24種不同的提示樣式後,模型分數對提示變化的敏感性從MMLU中的4-5%降低到MMLU-Pro中的僅2%。此外,我們發現使用鏈式思考(CoT)推理的模型在MMLU-Pro上比直接回答的表現更好,這與在原始MMLU上的發現形成鮮明對比,表明MMLU-Pro包含了更多複雜的推理問題。我們的評估確認,MMLU-Pro是一個更具區分性的基準測試,可以更好地追踪該領域的進展。

MMLU Pro 從 17 子分類簡化成 14 個子分類。一共有12032 個問題。比例如下圖。

其中 MMLU 原來的問題占了 56.6%。另外的部分是新加的問題。

image-20240702113632562

MMLU Pro 數據集的類別和子類別結構:

  • STEM (6 sub-categories, 和 MMLU 相同)
    • Mathematics
    • Physics
    • Chemistry
    • Biology
    • Computer Science
    • Engineering
  • Humanities (3 sub-categories, 和 MMLU 相同)
    • History
    • Philosophy
    • Law
  • Social Sciences (2 sub-categories,移除 Geography, Politics)
    • Economics
    • Psychology
  • **Other **(3 sub-categories,移除 Culture)
    • Health
    • Business
    • Other

MMLU Pro Dataset

第一步是 load dataset. 這裏使用 TIGER-Lab/MMLU-Pro, 基本是一個 MMLU 的 subset.

1
2
3
4
5
!pip install datasets
import datasets
#from datasets import load_dataset

dataset = datasets.load_dataset('TIGER-Lab/MMLU-Pro')

dataset 的結構如下:

1
2
3
4
5
6
7
8
9
10
DatasetDict({
    test: Dataset({
        features: ['question_id', 'question', 'options', 'answer', 'answer_index', 'cot_content', 'category', 'src'],
        num_rows: 12032
    })
    validation: Dataset({
        features: ['question_id', 'question', 'options', 'answer', 'answer_index', 'cot_content', 'category', 'src'],
        num_rows: 70
    })
})

Llama3-8B INT4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
accuracy:  computer science 0.3097560975609756
accuracy:  math 0.18134715025906736
accuracy:  chemistry 0.23586572438162545
accuracy:  engineering 0.29205366357069146
accuracy:  law 0.2561307901907357
accuracy:  biology 0.5564853556485355
accuracy:  health 0.3374083129584352
accuracy:  physics 0.2317167051578137
accuracy:  business 0.2623574144486692
accuracy:  philosophy 0.30060120240480964
accuracy:  economics 0.41706161137440756
accuracy:  other 0.2987012987012987
accuracy:  psychology 0.5275689223057645
accuracy:  history 0.3123359580052493

To compare with paper:

  Overall Math Physics Engineering History Law Psychology
  30.8 18.1 23.1 29.2 31.2 25.6 52.8
               
               

image-20240703101052696

使用 dataviewer

image-20240622174142179

一個記錄如下

1
2
3
4
5
6
7
8
9
10
11
12
13
print(dataset['test']['question_id'][0])
print(dataset['test']['question'][0])
print(dataset['test']['options'][0])
print(dataset['test']['answer'][0])
print(dataset['test']['answer_index'][0])
print(dataset['test']['category'][0])
#############################################
70 # id
Typical advertising regulatory bodies suggest, for example that adverts must not: encourage _________, cause unnecessary ________ or _____, and must not cause _______ offence.
['Safe practices, Fear, Jealousy, Trivial', 'Unsafe practices, Distress, Joy, Trivial', 'Safe practices, Wants, Jealousy, Trivial', 'Safe practices, Distress, Fear, Trivial', 'Unsafe practices, Wants, Jealousy, Serious', 'Safe practices, Distress, Jealousy, Serious', 'Safe practices, Wants, Fear, Serious', 'Unsafe practices, Wants, Fear, Trivial', 'Unsafe practices, Distress, Fear, Serious']
I
8
business # category

Open AI API

2024/6/19 GPT-4o 和 GPT-3.5 Turbo 的價格差。

GPT-3.5 Turbo 便宜 10 倍,但是準確率也比較差。

image-20240619083358544

GPT 設定

第二步是調用 gpt API,幾個重點:

  • 設定模型本身:
    • model = “gpt-4o” or “gpt-3.5-turbo-0125”
    • 溫度: T = 0 是 greedy decode. T = 0.1 還是以穩定爲主。如果 T = 1 則是創意爲主。
    • max_tokens: 最大的 context length, 也就是 KV cache size
    • top_p, frequency_penalty, presence_penalty: ?
  • 使用結構化 message 的 input prompt:
    • role: 訂人設
    • content: text 的 question (實際的 input)。應該可以加上 image 的content.
  • 回傳 reponse, 其結構應該和 input prompt 一樣

    • message.content: 這是 answer

    • choices? 是同時產生幾個不同的 choices?

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
!pip install openai
from openai import OpenAI
client = OpenAI(api_key='put the key')

def run_one_question(question: str):
    response = client.chat.completions.create(
        model="gpt-4o",  # "gpt-3.5-turbo"
        messages=[
            {
                "role": "system",
                "content": "You are an knowledge expert, you are supposed to answer the multi-choice question to derive your final answer as `The answer is ...`."
            },
            {
                "role": "user",
                "content": [
                    {
                    "type": "text",
                    "text": question
                    }
                ]
            }
        ],
        temperature=0.1,
        max_tokens=4096,
        top_p=1,
        frequency_penalty=0,
        presence_penalty=0,
    )

    return response.choices[0].message.content
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
def form_options(options: list):
    option_str = 'Options are:\n'
    opts = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
    for opt, o in zip(options, opts):
        option_str += f'({o}): {opt}' + '\n'
    return option_str


def get_prediction(output):
    pattern = r"answer is \(?([ABCDEFGHIJ])\)?"
    match = re.search(pattern, output)
    if match:
        return match.group(1)
    else:
        print("extraction failed, do a random guess")
        return random.choice(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'])
    
    
from tqdm import tqdm

print('----------------- Start Answering -------------------')
pbar = tqdm(dataset['test'], desc='Processing', unit='question')
for entry in pbar:
    prefix = prompts[entry['category']]  # prefix consists of examples, 4 shots
    query = prefix + 'Q: ' + entry['question'] + '\n' + form_options(entry['options']) + '\n'
    answer = run_one_question(query)  # answer is from GPT
    entry['solution'] = answer  # store the GPT answer, because entry['answer'] is used for ground truth, so use 'answer'
    answers.append(entry)
    prediction = get_prediction(answer) # get exact letter A, B, .. from GPT answer
    if entry["answer"] == prediction:   # compare ground truth with GPT answer
        success += 1
        per_category_accuracy[entry['category']][0] += 1
    else:
        fail += 1
        per_category_accuracy[entry['category']][1] += 1

    json_string = json.dumps(entry)
    file.write(json_string + '\n')

    success_rate = success / (success + fail)
    pbar.set_description(f'Processing (Success rate: {success_rate:.4f})')

for k, v in per_category_accuracy.items():
    if v[0] + v[1] > 0:
      print('accuracy: ', k, v[0] / (v[0] + v[1]))