中文域名.网站,短视频推广平台有哪些,包头市网站建设,注册百度推广账号文章目录 一、赛事概述1.1 OpenBookQA Dataset1.2 比赛背景1.3 评估方法和代码要求1.4 比赛数据集1.5 优秀notebook 二、BERT Baseline2.1 数据预处理2.2 定义data_collator2.3 加载模型#xff0c;配置trainer并训练2.4 预测结果并提交2.5 相关优化 前言#xff1a;国庆期间… 文章目录 一、赛事概述1.1 OpenBookQA Dataset1.2 比赛背景1.3 评估方法和代码要求1.4 比赛数据集1.5 优秀notebook 二、BERT Baseline2.1 数据预处理2.2 定义data_collator2.3 加载模型配置trainer并训练2.4 预测结果并提交2.5 相关优化 前言国庆期间哪也没去重装了win10conda和python环境然后重点解读
Kaggle - LLM Science Exam赛事的优秀代码希望可以学到些东西。 一、赛事概述
1.1 OpenBookQA Dataset OpenBookQA Dataset是由美国艾伦人工智能研究院Allen Institute for AI发布的一个问答技术评测集其主要目的是通过选择题考试的方式来测试和评估人工智能系统的问题回答能力以下是更详细的介绍。 发布背景 许多之前的阅读理解数据集都是基于抽取式的方法,只需要从给定的上下文中抽取答案,而没必要进行更深层次的推理。OpenBookQA要求模型需要利用基础知识来回答问题,进行更复杂的推理。 数据集构成 OpenBookQA包含5957个四选一的科学常识问题(4,957 train, 500 dev, 500 test)。这些问题需要根据包含1326个科学事实的小“书本”来回答。问题采样自维基百科页面。 模型表现 回答OpenBookQA的问题不仅需要给定知识库中的科学常识还需要额外的广泛常识知识。这些问题既不能通过检索算法回答正确也不能通过词语共现算法回答正确。Strong neural baselines在OpenBookQA上只能达到约50%的准确率与人类92%的准确率存在明显差距。 附加数据 该数据集还提供了5167个群众贡献的常识知识,以及扩展的训练集、开发集、测试集每个问题对应其所考察的核心科学事实、人类准确率、清晰度评分等信息。 数据集意义 OpenBookQA推动了机器阅读理解从抽取式到推理式的发展评估了模型在开放域知识下的深层理解和推理能力。
1.2 比赛背景 赛事地址Kaggle - LLM Science Exam LLM的能力随着大型语言模型的能力不断扩展研究领域中出现了使用LLMs来表征自身的趋势。因为许多现有的自然语言处理基准测试已经被最先进的模型轻松解决所以有趣的工作是利用LLMs创建更具挑战性的任务以测试更强大的模型。数据生成比赛使用了gpt3.5模型该模型基于从维基百科中提取的各种科学主题的文本片段要求它编写一个多项选择问题附带已知答案然后过滤掉简单的问题。资源受限本次比赛是一场代码比赛GPU和时间都受到限制。挑战性虽然量化和知识蒸馏等技术可以有效地缩小语言模型以便在更少的硬件资源上运行但这场比赛仍旧充满挑战。目前目前在 Kaggle 上运行的最大模型有大约 100 亿个参数而 gpt3.5 有 1750 亿个参数。如果一个问答模型能够轻松通过一个比其规模大10倍以上的模型编写的问答测试这将是一个真正有趣的结果。另一方面如果更大的模型能够有效地难住较小的模型这对LLMs自我评估和测试的能力具有引人注目的影响。竞赛旨在探讨比gpt3.5小10倍以上的问答模型能否有效回答gpt3.5编写的问题。结果将揭示LLM的基准测试和自我测试能力。
1.3 评估方法和代码要求
提交根据平均精度 3 MAP3 进行评估 其中 为测试集中的问题数量() 为截断值为 时的精确度 为每个问题的预测数量() 为指示函数如果排名为 的项目是相关的正确的标签则等于1否则为0。 另外某个问题正确预测后后续将跳过该标签的其他预测以防止刷准确度。举例来说假设有一个测试集里面有3个问题的正确答案都是A如果有一个模型对这3个问题给出以下答案那么以下情况都会得到平均精确度1.0的分数
[A, B, C, D, E] # 问题1预测
[A, A, A, A, A] # 问题2预测
[A, B, A, C, A] # 问题3预测这意味着一旦找到正确答案A之后的预测不再影响平均精确度分数。 本次比赛必须以notebook提交且CPU和GPU运行时间少于9小时。禁用互联网但是允许使用公开的外部数据包括预先训练的模型。另外提交文件必须命名为 submission.csv。
1.4 比赛数据集 本次比赛是回答由gpt3.5模型生成的4000道多选题组成的测试集。测试集是隐藏的当提交notebook后才会有实际的测试数据进行评测。
train.csv 200个样本问题答案以显示数据格式并大致了解测试集中的问题类型。test.csv 测试集只包含题目答案省略。sample_submission.csv 提交格式示例
具体的训练集格式如下
# Lets import the public training set and take a look
import pandas as pdtrain_df pd.read_csv(/kaggle/input/kaggle-llm-science-exam/train.csv)
train_df.head()对于测试集中的每个 id 标签您最多可以预测 3 个标签 。submission.csv文件应包含header并具有以下格式
id,prediction
0, A B C
1, B C A
2, C A B
etc.1.5 优秀notebook 《Starter Notebook: Ranked Predictions with BERT》Bert Baseline使用bert-base-cased和比赛提供的200个训练集样本进行训练Public Score0.545 《[EDA, Data gathering] LLM-SE ~ Wiki STEM | 1k DS》比赛提供的200个样本太少了作者LEONID KULYK先分析了比赛数据集然后同样使用 gpt3.5 上收集了1000个Wikipedia样本即Wikipedia STEM 1k 《LLM-SE ~ deberta-v3-large -i | 1k Wiki》:LEONID KULYK使用自己收集的1000个Wikipedia样本和比赛训练集样本一起训练模型是deberta-v3-large。notebook中有最终模型权重可直接推理LB 0.709。 《New dataset DEBERTA v3 large training!》0.723→0.759 Radek 基于LEONID KULYK的工作使用自己生成的500个额外数据训练DEBERTA v3 largePublic Score0.723。作者后来又生成了6000条数据融合为6.5K数据集并在此基础上训练模型得到了三个模型权重上传在Science Exam Trained Model Weights。通过《Inference using 3 trained Deberta v3 models》三个模型分别预测之后概率取平均Public Score0.737。而使用Voting Ensemble集成投票Public Score0.759作者最后上传了15k high-quality train examples 《Open Book LLM Science Exam》jjinho首次提出了Open Book方法 《Open Book LLM Science Exam - Reduced RAM usage》quangbk改进了jjinho方法中的内存效率。 《OpenBook DeBERTaV3-Large Baseline (Single Model》) Anil将quangbk的Open Book方法与Radek的DEBERTA v3 large training结合起来Public Score0.771 《Sharing my trained-with-context model》Mgoksu对 ANIL的方法中的DeBerta large进行微调使用了自己制作的数据集top public LB0.807 《How To Train Open Book Model - Part 1》、《How To Train Open Book Model - Part 2》CHRIS DEOTTE在mgoksu的基础上加入自己制作的60k数据集进行训练设置NUM_TITLES_INCLUDE 5 和 NUM_SENTENCES_INCLUDE 20Public Score0.819 《LLM Science Exam Optimise Ensemble Weights》作者主要基于CHRIS DEOTTE的工作使用了他训练的模型权重。另外为了增加多样性还融合了其它几个没有使用Open Book的deberta-v3-large模型Public Score0.837。作者还写了《Using DeepSpeed with HF Trainer》等等 《LLM-SciEx Optimise Ensemble Weights(better models)》通过模型融合Public Score0.846 《with only 270K articles》作者自己制作了270K Wikipedia数据使用LongFormer 模型进行训练Public Score0.862 《Platypus2-70B with Wikipedia RAG》SIMJEG结合了上述方法8和12最终Public Score0.872。做了详细的解释。ALI在 《Explained Platypus2-70B Wikipedia RAG》中对SIMJEG的notebook做了详细的说明。
二、BERT Baseline 此部分参考《Starter Notebook: Ranked Predictions with BERT》作者直接使用bert_base模型对训练集中的200个样本进行3个epoch的训练然后再进行推理。大部分代码参考的是HF官方文档《Multiple choice》
2.1 数据预处理
import pandas as pd
from datasets import Datasettrain_df pd.read_csv(/kaggle/input/kaggle-llm-science-exam/train.csv)
train_ds Dataset.from_pandas(train_df)
train_df.head()from transformers import AutoTokenizermodel_dir bert-base-cased
tokenizer AutoTokenizer.from_pretrained(model_dir)options ABCDE
indices list(range(5))
option_to_index {option: index for option, index in zip(options, indices)}
index_to_option {index: option for option, index in zip(options, indices)}def preprocess(example):# AutoModelForMultipleChoice 需要的是question/answer对所以问题被复制5次first_sentence [example[prompt]] * 5second_sentence []# 遍历选项A 到 E并将它们添加到 second_sentence 列表中for option in options:second_sentence.append(example[option])tokenized_example tokenizer(first_sentence, second_sentence, truncationTrue)# 将答案映射为索引并将其添加到 tokenized_example 中作为标签tokenized_example[label] option_to_index[example[answer]]return tokenized_example# 使用数据集映射map预处理函数到训练数据集同时删除不需要的列
tokenized_train_ds train_ds.map(preprocess, batchedFalse, remove_columns[prompt, A, B, C, D, E, answer])
print(tokenized_train_ds[0]){id: 1, input_ids: [[101, 5979, ...], [101, 5979, ...], [101, 5979, ...], [101, 5979, ...], [101, 5979, ...]], token_type_ids: [[0, 0, ...], [0, 0, ...],[0, 0, ...],[0, 0, ...],[0, 0, ...]], attention_mask: [[1, 1,...],[1, 1,...],[1, 1,...],[1, 1,...],[1, 1,...]], label: 0}可以看到每个样本的问题被重复5次后和5个选项合并解码后的结果input_ids、token_type_ids、attention_mask都是5个元素的嵌套列表等于一个样本被拆成5个样本。 有关填充和截断的详细信息可参考官方文档《Padding and truncation》 2.2 定义data_collator
# datacollator 来自 https://huggingface.co/docs/transformers/tasks/multiple_choice
# 每个batch中对问答对进行动态填充dynamically pad所以不需要将每个问答对都填充到模型最大序列长度
from dataclasses import dataclass
from transformers.tokenization_utils_base import PreTrainedTokenizerBase, PaddingStrategy
from typing import Optional, Union
import torchdataclass
class DataCollatorForMultipleChoice:tokenizer: PreTrainedTokenizerBasepadding: Union[bool, str, PaddingStrategy] Truemax_length: Optional[int] Nonepad_to_multiple_of: Optional[int] Nonedef __call__(self, features):# features就是4个样本batch size4)label_name label if label in features[0].keys() else labels# 对每个样本feature字典格式使用pop删除key为label的键值对返回被删除的值# 所以feature被删除了label键值对而labels的值是四个样本label列表[0, 0, 1, 0]labels [feature.pop(label_name) for feature in features] batch_size len(features) # 批次大小num_choices len(features[0][input_ids]) # 选项数flattened_features [[{k: v[i] for k, v in feature.items()} for i in range(num_choices)] for feature in features]flattened_features sum(flattened_features, [])batch self.tokenizer.pad(flattened_features,paddingself.padding,max_lengthself.max_length,pad_to_multiple_ofself.pad_to_multiple_of,return_tensorspt,)batch {k: v.view(batch_size, num_choices, -1) for k, v in batch.items()}batch[labels] torch.tensor(labels, dtypetorch.int64)return batch传入数据features为四个样本数据每个样本格式和tokenized_train_ds[0]的格式一样 [{input_ids: [...], token_type_ids: [...], attention_mask: [...], label: 0},
{input_ids: [...], token_type_ids: [...], attention_mask: [...], label: 0},
{input_ids: [...], token_type_ids: [...], attention_mask: [...], label: 1},
{input_ids: [...], token_type_ids: [...], attention_mask: [...], label: 0}]去除label标签labels [feature.pop(label_name) for feature in features] 通过字典的pop方法去除了每个样本中的label键值对并将label的值取出最终labels[0, 0, 1, 0]。这一步之后每个feature为 {input_ids: [[...], [...], [...], [...], [...]], token_type_ids: [[...], [...], [...], [...], [...]], attention_mask: [[...], [...], [...], [...], [...]]}执行flattened操作此时flattened_features为 [[{input_ids: ..., token_type_ids: ..., attention_mask: ...}, {...}, {...}, {...}, {...}],
[{...}, {...}, {...}, {...}, {...}],
[{...}, {...}, {...}, {...}, {...}],[{...}, {...}, {...}, {...}, {...}]]sum(flattened_features, [])操作后flattened_features为 # 加和操作后的flattened_features成了20个样本
[{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]},
{input_ids: [...], token_type_ids: [...], attention_mask: [...]}, ...]这一步是将嵌套列表转为一维列表方便后续解码时方便进行pad和batch操作。
最终结果为
{input_ids: tensor([[[ 101, 2627..., 0]]]),
token_type_ids: tensor([[[0, 0, 0, ..., 0, 0]]]),
attention_mask: tensor([[[1, 1, 1, ..., 0, 0]]]),
labels: tensor([0, 0, 1, 0])}2.3 加载模型配置trainer并训练
from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer
model AutoModelForMultipleChoice.from_pretrained(model_dir)output_dir finetuned_bert
training_args TrainingArguments(output_diroutput_dir,evaluation_strategyepoch,save_strategyepoch,load_best_model_at_endTrue,learning_rate5e-5,per_device_train_batch_size4,per_device_eval_batch_size4,num_train_epochs3,weight_decay0.01,report_tonone)trainer Trainer(modelmodel,argstraining_args,train_datasettokenized_train_ds,eval_datasettokenized_train_ds,tokenizertokenizer,data_collatorDataCollatorForMultipleChoice(tokenizertokenizer))trainer.train()Epoch Training Loss Validation Loss
1 No log 1.564447
2 No log 1.527968
3 No log 1.4173412.4 预测结果并提交
直接使用trainer预测
test_df pd.read_csv(/kaggle/input/kaggle-llm-science-exam/test.csv)
# 测试集没有answer列加上这一列以保持和训练集格式一致方便使用同样的处理方式
test_df[answer] A
test_ds Dataset.from_pandas(test_df)
tokenized_test_ds test_ds.map(preprocess, batchedFalse, remove_columns[prompt, A, B, C, D, E, answer])test_predictions trainer.predict(tokenized_test_ds) # 结果是PredictionOutput格式包含predictions、label_ids、metrics三个字段
test_df.head()import numpy as np
def predictions_to_map_output(predictions):# 对每一行的预测结果按照降序排列并获取每行的前三个答案的索引# np.argsort默认是对列表中元素值进行升序排列并返回排序后元素值对应的索引top_answer_indices np.argsort(-predictions)[:,:3]top_answers [ .join([index_to_option[idx] for idx in row]) for row in top_answer_indices]return top_answers# 获取测试集的id列作为提交文件的id列
submission_df test_df[[id]]
submission_df[prediction] predictions_to_map_output(test_predictions.predictions)
submission_df.head()id prediction
0 0 D B E
1 1 B A D
2 2 A C D
3 3 C D A
4 4 E D C重新加载模型预测
如果是重新打开notebook后再预测需要先加载模型设置推理的trainer参数再进行预测
from transformers import AutoModelForMultipleChoice, TrainingArguments, Trainer
model_checkpoint finetuned_bert/checkpoint-150
model AutoModelForMultipleChoice.from_pretrained(model_dir)
tokenizer AutoTokenizer.from_pretrained(model_checkpoint)# 只进行推理
inference_args TrainingArguments(output_dir./inference_results, # 推理结果的保存目录per_device_eval_batch_size8, # 每个设备的推理批量大小
)trainer Trainer(modelmodel, # 已加载的模型eval_datasettokenized_test_ds,argsinference_args, # 推理的参数data_collatorDataCollatorForMultipleChoice(tokenizertokenizer)
)test_predictions trainer.predict(tokenized_test_ds) 后面的步骤都一样了。
2.5 相关优化
《LLM-SE ~ deberta-v3-large -i | 1k Wiki》:LEONID KULYK使用自己收集的1000个Wikipedia样本和比赛训练集样本一起训练模型是deberta-v3-large。notebook中有最终模型权重可直接推理LB 0.709。《New dataset DEBERTA v3 large training!》0.723→0.759 Radek 基于LEONID KULYK的工作使用自己生成的500个额外数据训练DEBERTA v3 largePublic Score0.723。作者后来又生成了6000条数据融合为6.5K数据集并在此基础上训练模型得到了三个模型权重上传在Science Exam Trained Model Weights。通过《Inference using 3 trained Deberta v3 models》三个模型分别预测之后概率取平均Public Score0.737。而使用Voting Ensemble集成投票Public Score0.759作者最后上传了15k high-quality train examples