mirror of
https://github.com/EleutherAI/lm-evaluation-harness.git
synced 2026-10-11 21:59:53 +00:00
add pre-commit
This commit is contained in:
+2
-2
@@ -1,7 +1,7 @@
|
||||
[run]
|
||||
|
||||
# tasks that aren't wired up.
|
||||
omit =
|
||||
omit =
|
||||
lm_eval/tasks/quac.py
|
||||
lm_eval/tasks/storycloze.py
|
||||
lm_eval/tasks/cbt.py
|
||||
@@ -25,4 +25,4 @@ exclude_lines =
|
||||
# Don't complain if tests don't hit defensive assertion code:
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
return NotImplemented
|
||||
return NotImplemented
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[flake8]
|
||||
ignore = E203, E266, E501, W503, F403, F401, C901
|
||||
max-line-length = 127
|
||||
max-complexity = 10
|
||||
select = B,C,E,F,W,T4,B9
|
||||
@@ -0,0 +1,13 @@
|
||||
name: Pull Request
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: pre-commit/[email protected]
|
||||
+1
-1
@@ -2,4 +2,4 @@ env
|
||||
*.pyc
|
||||
data/
|
||||
lm_cache
|
||||
.idea
|
||||
.idea
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.1.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-ast
|
||||
- id: check-byte-order-marker
|
||||
- id: check-case-conflict
|
||||
- id: check-json
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-yaml
|
||||
- id: destroyed-symlinks
|
||||
- id: detect-private-key
|
||||
- id: end-of-file-fixer
|
||||
- id: no-commit-to-branch
|
||||
- id: requirements-txt-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: fix-byte-order-marker
|
||||
exclude: docs/CNAME
|
||||
- id: fix-encoding-pragma
|
||||
args: [--remove]
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=lf]
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.7.9
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3.8
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.1.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: [
|
||||
"--ignore-words-list=reord", # Word used in error messages that need rewording
|
||||
--check-filenames,
|
||||
--check-hidden,
|
||||
]
|
||||
@@ -3,7 +3,7 @@
|
||||

|
||||
[](https://codecov.io/gh/EleutherAI/lm-evaluation-harness)
|
||||
|
||||
## Overview
|
||||
## Overview
|
||||
|
||||
This project provides a unified framework to test autoregressive language models (GPT-2, GPT-3, GPTNeo, etc) on a large number of different evaluation tasks.
|
||||
|
||||
@@ -403,7 +403,7 @@ the ngram files and info.json. See the above guide for ngram generation for the
|
||||
python main.py \
|
||||
--model gpt2 \
|
||||
--device 0 \
|
||||
--tasks sciq \
|
||||
--tasks sciq \
|
||||
--decontamination_ngrams_path path/containing/training/set/ngrams
|
||||
```
|
||||
|
||||
@@ -420,9 +420,9 @@ Both LMs (`lm_eval.models`) and Tasks (`lm_eval.tasks`) are kept in a registry d
|
||||
|
||||
The [GPT-3 Evaluations Project](https://github.com/EleutherAI/lm_evaluation_harness/projects/1) tracks our progress implementing new tasks. Right now, we are focused on getting all the datasets loaded so that we can dedupe against the training data. Implementing the actual evaluations is nice but not necessary at the current moment.
|
||||
|
||||
### Task Versioning
|
||||
### Task Versioning
|
||||
|
||||
To help improve reproducibility, all tasks have a VERSION field. When run from the command line, this is reported in a column in the table, or in the "version" field in the evaluator return dict. The purpose of the version is so that if the task definition changes (i.e to fix a bug), then we can know exactly which metrics were computed using the old buggy implementation to avoid unfair comparisons. To enforce this, there are unit tests that make sure the behavior of all tests remains the same as when they were first implemented. Task versions start at 0, and each time a breaking change is made, the version is incremented by one.
|
||||
To help improve reproducibility, all tasks have a VERSION field. When run from the command line, this is reported in a column in the table, or in the "version" field in the evaluator return dict. The purpose of the version is so that if the task definition changes (i.e to fix a bug), then we can know exactly which metrics were computed using the old buggy implementation to avoid unfair comparisons. To enforce this, there are unit tests that make sure the behavior of all tests remains the same as when they were first implemented. Task versions start at 0, and each time a breaking change is made, the version is incremented by one.
|
||||
|
||||
When reporting eval harness results, please also report the version of each task. This can be done either with a separate column in the table, or by reporting the task name with the version appended as such: taskname-v0.
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@ The basis for our decontamination procedure can be found in Appendix C of "Langu
|
||||
|
||||
## Implementation
|
||||
|
||||
Contamination detection can be found in "lm_eval/decontaminate.py" with supporting code in "lm_eval/decontamination/".
|
||||
Contamination detection can be found in "lm_eval/decontaminate.py" with supporting code in "lm_eval/decontamination/".
|
||||
|
||||
decontaminate.py does the following:
|
||||
1. Build dictionaries of all ngrams and their corresponding evaluation/document ids.
|
||||
2. Scan through sorted files containing training set n-grams.
|
||||
3. If a match is found, the corresponding evaluation/document combinations are marked as contaminated.
|
||||
|
||||
"lm_eval/evaluator.py" can then produce a clean version of the benchmark by excluding the results of contaminated documents. For each metric, a clean version will be shown in the results with a "decontaminate" suffix.
|
||||
"lm_eval/evaluator.py" can then produce a clean version of the benchmark by excluding the results of contaminated documents. For each metric, a clean version will be shown in the results with a "decontaminate" suffix.
|
||||
|
||||
This is disabled by default for new tasks, to support decontamination on a task override the "should_decontaminate" and "doc_to_decontamination_query" methods. For more details see the [task guide](task_guide.md).
|
||||
|
||||
@@ -73,4 +73,3 @@ python -m scripts/clean_training_data/compress_and_package \
|
||||
```
|
||||
|
||||
Congratulations, the final directory can now be passed to lm-evaulation-harness with the "--decontamination_ngrams_path" argument.
|
||||
|
||||
|
||||
+9
-9
@@ -16,7 +16,7 @@ pip install -e ".[dev]"
|
||||
|
||||
## Creating Your Task File
|
||||
|
||||
From the `lm-evaluation-harness` project root, copy over the `new_task.py` template to `lm_eval/datasets`.
|
||||
From the `lm-evaluation-harness` project root, copy over the `new_task.py` template to `lm_eval/datasets`.
|
||||
|
||||
```sh
|
||||
cp templates/new_task.py lm_eval/tasks/<task-name>.py
|
||||
@@ -52,7 +52,7 @@ For example, take the QuAC dataset. We have:
|
||||
QuAC: Question Answering in Context
|
||||
https://arxiv.org/abs/1808.07036
|
||||
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
participating in information seeking dialog. Data instances consist of an interactive
|
||||
dialog between two crowd workers: (1) a student who poses a sequence of freeform
|
||||
questions to learn as much as possible about a hidden Wikipedia text, and (2)
|
||||
@@ -72,7 +72,7 @@ Now let's walk through the actual implementation - from data handling to evaluat
|
||||
### Downloading your Data
|
||||
|
||||
All data downloading and management is handled through the HuggingFace (**HF**) [`datasets`](https://github.com/huggingface/datasets) API. So, the first thing you should do is check to see if your task's dataset is already provided in their catalog [here](https://huggingface.co/datasets). If it's not in there, please consider adding it to their Hub to make it accessible to a wider user base by following their [new dataset guide](https://github.com/huggingface/datasets/blob/master/ADD_NEW_DATASET.md)
|
||||
.
|
||||
.
|
||||
Now, that you have your HF dataset, you need to assign its path and name to your `Task` in the following fields:
|
||||
|
||||
```python
|
||||
@@ -116,7 +116,7 @@ These should return a Python iterable (`list` or `generator`) of `dict`s that ca
|
||||
|
||||
#### Processing Documents
|
||||
|
||||
At this point, you can also process each individual document to, for example, strip whitespace or "detokenize" its fields. Put the processing logic into `_process_doc` and map the functions across training/validation/test docs inside of the respective functions.
|
||||
At this point, you can also process each individual document to, for example, strip whitespace or "detokenize" its fields. Put the processing logic into `_process_doc` and map the functions across training/validation/test docs inside of the respective functions.
|
||||
🔠 If your task is **multiple-choice**, we require you to format your documents such that they contain `gold` and `choices` fields. They can also have other fields, but those will be ignored by `MultipleChoiceTask`. `choices` should be a list of possible continuations, and `gold` should be an integer specifying the index of the correct completion.
|
||||
See [this task](https://github.com/EleutherAI/lm-evaluation-harness/blob/6caa0afd96a7a7efb2ec4c1f24ad1756e48f3aa7/lm_eval/tasks/sat.py#L60) for an example. 🔠
|
||||
|
||||
@@ -154,7 +154,7 @@ Finally, be aware that the strings from `doc_to_text` and `doc_to_target` will b
|
||||
### Decontamination
|
||||
For background on decontamination please see [this](./decontamination.md).
|
||||
|
||||
If you wish to support decontamination studies for your task simply override the "should_decontaminate" method and return true.
|
||||
If you wish to support decontamination studies for your task simply override the "should_decontaminate" method and return true.
|
||||
|
||||
You also need to override "doc_to_decontamination_query" and return the data you wish to compare against the training set. This doesn't necessarily need to be the full document or request, and we leave this up to the implementor. For a multi-choice evaluation you could for example just return the question.
|
||||
|
||||
@@ -172,7 +172,7 @@ python -m scripts.write_out \
|
||||
--tasks <your-task> \
|
||||
--sets <train | val | test> \
|
||||
--num_fewshot K \
|
||||
--num_examples N \
|
||||
--num_examples N \
|
||||
--description_dict_path <path>
|
||||
```
|
||||
|
||||
@@ -199,9 +199,9 @@ def construct_requests(self, doc, ctx):
|
||||
"""
|
||||
return ...
|
||||
```
|
||||
#### What's a `Request`? What's a `doc`?
|
||||
#### What's a `Request`? What's a `doc`?
|
||||
To reiterate, a `doc` is just a `Dict` object that contains information about a document from your corpus. It can contain things like a prompt, question type information, answers and anything else you think will be needed in order to assess your model for a given task. Keep in mind that the fields of this can be basically whatever you want (you can sort this out in `training_docs` \ `validation_docs` \ `test_docs` if you need to customise things - see above), just remember to be consistent with them throughout the rest of the `Task` you write up.
|
||||
A `Request` is an object that takes the text prompt you want to present to a model and computes one of a few different types of response. These are evaluated lazily (meaning, only when the result is actually needed). If your task requires generating text you'll need to return a `rf.greedy_until` request otherwise an `rf.loglikelihood` across all labels in a classification tasks will do.
|
||||
A `Request` is an object that takes the text prompt you want to present to a model and computes one of a few different types of response. These are evaluated lazily (meaning, only when the result is actually needed). If your task requires generating text you'll need to return a `rf.greedy_until` request otherwise an `rf.loglikelihood` across all labels in a classification tasks will do.
|
||||
The function `construct_requests` can return a list of `Request`s or an iterable; it's perfectly fine to `yield` them from something or other. This is particularly handy if you are creating more than one request per `doc` (usually because you're up to something like multi-task learning). The objects this function returns then get consumed one by one and turned into result objects.
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ def aggregation(self):
|
||||
```
|
||||
In `process_results`, model outputs are converted into metrics. These metrics are per document metrics, however; the `aggregation` function is used to work out what to do with them to create a corpus-level metric. Imagine you have a bunch of documents, for each of which you have calculated an F1 score. What should that mean overall? Should they be summed, averaged, the min/max found? This function handles that problem.
|
||||
|
||||
The contents of the function itself are pretty straightforward; it should simply return a dict that maps from each metric label that could be returned by `process_results` to a function that can be used to aggregate that metric. That is to say, if the metrics that `process_results` could return are given by `{'a', 'b', 'c'}`, then all of these keys should be present in the dict returned by `aggregation`.
|
||||
The contents of the function itself are pretty straightforward; it should simply return a dict that maps from each metric label that could be returned by `process_results` to a function that can be used to aggregate that metric. That is to say, if the metrics that `process_results` could return are given by `{'a', 'b', 'c'}`, then all of these keys should be present in the dict returned by `aggregation`.
|
||||
__NOTE__: See `lm_eval/metrics.py` for a few "built-in" aggregate metrics you can easily import. The standard metrics available in this package are generally based on `sklearn` functions, so if you are in any doubt for how to set things up the documentation over there can be of assistance. If you need to write a custom metric for some reason, start by looking at the existing ones in `lm_eval/metrics.py` for an idea about what the function signature needs to be.
|
||||
|
||||
```python
|
||||
|
||||
+161
-99
@@ -24,17 +24,17 @@ class LM(abc.ABC):
|
||||
@abstractmethod
|
||||
def loglikelihood(self, requests):
|
||||
"""Compute log-likelihood of generating a continuation from a context.
|
||||
Downstream tasks should attempt to use loglikelihood instead of other
|
||||
Downstream tasks should attempt to use loglikelihood instead of other
|
||||
LM calls whenever possible.
|
||||
|
||||
:param requests: list
|
||||
A list of pairs (context, continuation)
|
||||
context: str
|
||||
Context string. Implementations of LM must be able to handle an
|
||||
Context string. Implementations of LM must be able to handle an
|
||||
empty context string.
|
||||
continuation: str
|
||||
The continuation over which log likelihood will be calculated. If
|
||||
there is a word boundary, the space should be in the continuation.
|
||||
The continuation over which log likelihood will be calculated. If
|
||||
there is a word boundary, the space should be in the continuation.
|
||||
For example, context="hello" continuation=" world" is correct.
|
||||
:return: list
|
||||
A list of pairs (logprob, isgreedy)
|
||||
@@ -97,7 +97,7 @@ class LM(abc.ABC):
|
||||
context: str
|
||||
Context string
|
||||
until: [str]
|
||||
The string sequences to generate until. These string sequences
|
||||
The string sequences to generate until. These string sequences
|
||||
may each span across multiple tokens, or may be part of one token.
|
||||
:return: list
|
||||
A list of strings continuation
|
||||
@@ -118,7 +118,6 @@ class LM(abc.ABC):
|
||||
|
||||
|
||||
class BaseLM(LM):
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def eot_token_id(self):
|
||||
@@ -145,13 +144,16 @@ class BaseLM(LM):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def tok_encode(self, string: str): pass
|
||||
|
||||
@abstractmethod
|
||||
def tok_decode(self, tokens: Iterable[int]): pass
|
||||
def tok_encode(self, string: str):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def _model_generate(self, context, max_length, eos_token_id): pass
|
||||
def tok_decode(self, tokens: Iterable[int]):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def _model_generate(self, context, max_length, eos_token_id):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def _model_call(self, inps):
|
||||
@@ -187,23 +189,30 @@ class BaseLM(LM):
|
||||
# TODO: automatic batch size detection for vectorization
|
||||
|
||||
loglikelihoods = []
|
||||
for string, in tqdm(requests):
|
||||
rolling_token_windows = list(map(utils.make_disjoint_window, utils.get_rolling_token_windows(
|
||||
token_list=self.tok_encode(string),
|
||||
prefix_token=self.eot_token_id,
|
||||
max_seq_len=self.max_length,
|
||||
context_len=1,
|
||||
)))
|
||||
for (string,) in tqdm(requests):
|
||||
rolling_token_windows = list(
|
||||
map(
|
||||
utils.make_disjoint_window,
|
||||
utils.get_rolling_token_windows(
|
||||
token_list=self.tok_encode(string),
|
||||
prefix_token=self.eot_token_id,
|
||||
max_seq_len=self.max_length,
|
||||
context_len=1,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
rolling_token_windows = [(None,) + x for x in rolling_token_windows]
|
||||
|
||||
# TODO: extract out this call so it only gets called once and also somehow figure out partial caching for
|
||||
# that
|
||||
string_nll = self._loglikelihood_tokens(rolling_token_windows, disable_tqdm=True)
|
||||
|
||||
string_nll = self._loglikelihood_tokens(
|
||||
rolling_token_windows, disable_tqdm=True
|
||||
)
|
||||
|
||||
# discard is_greedy
|
||||
string_nll = [x[0] for x in string_nll]
|
||||
|
||||
|
||||
string_nll = sum(string_nll)
|
||||
loglikelihoods.append(string_nll)
|
||||
|
||||
@@ -223,10 +232,12 @@ class BaseLM(LM):
|
||||
|
||||
toks = x[1] + x[2]
|
||||
return -len(toks), tuple(toks)
|
||||
|
||||
|
||||
# TODO: automatic (variable) batch size detection for vectorization
|
||||
reord = utils.Reorderer(requests, _collate)
|
||||
for chunk in utils.chunks(tqdm(reord.get_reordered(), disable=disable_tqdm), self.batch_size):
|
||||
for chunk in utils.chunks(
|
||||
tqdm(reord.get_reordered(), disable=disable_tqdm), self.batch_size
|
||||
):
|
||||
inps = []
|
||||
cont_toks_list = []
|
||||
inplens = []
|
||||
@@ -252,44 +263,60 @@ class BaseLM(LM):
|
||||
|
||||
# when too long to fit in context, truncate from the left
|
||||
inp = torch.tensor(
|
||||
(context_enc + continuation_enc)[-(self.max_length+1):][:-1],
|
||||
dtype=torch.long
|
||||
(context_enc + continuation_enc)[-(self.max_length + 1) :][:-1],
|
||||
dtype=torch.long,
|
||||
).to(self.device)
|
||||
inplen, = inp.shape
|
||||
(inplen,) = inp.shape
|
||||
|
||||
cont = continuation_enc
|
||||
|
||||
# since in _collate we make sure length is descending, the longest is always the first one.
|
||||
padding_length = padding_length if padding_length is not None else inplen
|
||||
padding_length = (
|
||||
padding_length if padding_length is not None else inplen
|
||||
)
|
||||
|
||||
# pad length from seq to padding_length
|
||||
inp = torch.cat([
|
||||
inp, # [seq]
|
||||
torch.zeros(padding_length - inplen, dtype=torch.long).to(inp.device) # [padding_length - seq]
|
||||
], dim=0)
|
||||
inp = torch.cat(
|
||||
[
|
||||
inp, # [seq]
|
||||
torch.zeros(padding_length - inplen, dtype=torch.long).to(
|
||||
inp.device
|
||||
), # [padding_length - seq]
|
||||
],
|
||||
dim=0,
|
||||
)
|
||||
|
||||
inps.append(inp.unsqueeze(0)) # [1, padding_length]
|
||||
cont_toks_list.append(cont)
|
||||
inplens.append(inplen)
|
||||
|
||||
batched_inps = torch.cat(inps, dim=0) # [batch, padding_length
|
||||
multi_logits = F.log_softmax(self._model_call(batched_inps), dim=-1).cpu() # [batch, padding_length, vocab]
|
||||
multi_logits = F.log_softmax(
|
||||
self._model_call(batched_inps), dim=-1
|
||||
).cpu() # [batch, padding_length, vocab]
|
||||
|
||||
for (cache_key, _, _), logits, inp, inplen, cont_toks \
|
||||
in zip(chunk, multi_logits, inps, inplens, cont_toks_list):
|
||||
for (cache_key, _, _), logits, inp, inplen, cont_toks in zip(
|
||||
chunk, multi_logits, inps, inplens, cont_toks_list
|
||||
):
|
||||
|
||||
# Slice to original seq length
|
||||
contlen = len(cont_toks)
|
||||
logits = logits[inplen-contlen:inplen].unsqueeze(0) # [1, seq, vocab]
|
||||
logits = logits[inplen - contlen : inplen].unsqueeze(
|
||||
0
|
||||
) # [1, seq, vocab]
|
||||
|
||||
# Check if per-token argmax is exactly equal to continuation
|
||||
greedy_tokens = logits.argmax(dim=-1)
|
||||
cont_toks = torch.tensor(cont_toks, dtype=torch.long).unsqueeze(0) # [1, seq]
|
||||
cont_toks = torch.tensor(cont_toks, dtype=torch.long).unsqueeze(
|
||||
0
|
||||
) # [1, seq]
|
||||
max_equal = (greedy_tokens == cont_toks).all()
|
||||
|
||||
# Obtain log-probs at the corresponding continuation token indices
|
||||
# last_token_slice = logits[:, -1, :].squeeze(0).tolist()
|
||||
logits = torch.gather(logits, 2, cont_toks.unsqueeze(-1)).squeeze(-1) # [1, seq]
|
||||
logits = torch.gather(logits, 2, cont_toks.unsqueeze(-1)).squeeze(
|
||||
-1
|
||||
) # [1, seq]
|
||||
|
||||
# Answer: (log prob, is-exact-match)
|
||||
answer = (float(logits.sum()), bool(max_equal))
|
||||
@@ -301,9 +328,9 @@ class BaseLM(LM):
|
||||
res.append(answer)
|
||||
|
||||
return reord.get_original(res)
|
||||
|
||||
|
||||
def greedy_until(self, requests):
|
||||
# TODO: implement fully general `until` that handles untils that are
|
||||
# TODO: implement fully general `until` that handles untils that are
|
||||
# multiple tokens or that span multiple tokens correctly
|
||||
|
||||
# TODO: extract to TokenizedLM?
|
||||
@@ -312,29 +339,33 @@ class BaseLM(LM):
|
||||
def _collate(x):
|
||||
toks = self.tok_encode(x[0])
|
||||
return len(toks), x[0]
|
||||
|
||||
|
||||
reord = utils.Reorderer(requests, _collate)
|
||||
|
||||
for context, until in tqdm(reord.get_reordered()):
|
||||
if isinstance(until, str):
|
||||
until = [until]
|
||||
|
||||
primary_until, = self.tok_encode(until[0])
|
||||
|
||||
context_enc = torch.tensor([self.tok_encode(context)[self.max_gen_toks - self.max_length:]]).to(self.device)
|
||||
(primary_until,) = self.tok_encode(until[0])
|
||||
|
||||
cont = self._model_generate(context_enc, context_enc.shape[1] + self.max_gen_toks, primary_until)
|
||||
context_enc = torch.tensor(
|
||||
[self.tok_encode(context)[self.max_gen_toks - self.max_length :]]
|
||||
).to(self.device)
|
||||
|
||||
s = self.tok_decode(cont[0].tolist()[context_enc.shape[1]:])
|
||||
cont = self._model_generate(
|
||||
context_enc, context_enc.shape[1] + self.max_gen_toks, primary_until
|
||||
)
|
||||
|
||||
s = self.tok_decode(cont[0].tolist()[context_enc.shape[1] :])
|
||||
|
||||
for term in until:
|
||||
s = s.split(term)[0]
|
||||
|
||||
|
||||
# partial caching
|
||||
self.cache_hook.add_partial("greedy_until", (context, until), s)
|
||||
|
||||
|
||||
res.append(s)
|
||||
|
||||
|
||||
return reord.get_original(res)
|
||||
|
||||
|
||||
@@ -383,7 +414,7 @@ class Task(abc.ABC):
|
||||
self._fewshot_docs = None
|
||||
|
||||
def download(self, data_dir=None, cache_dir=None, download_mode=None):
|
||||
""" Downloads and returns the task dataset.
|
||||
"""Downloads and returns the task dataset.
|
||||
Override this method to download the dataset from a custom API.
|
||||
|
||||
:param data_dir: str
|
||||
@@ -412,7 +443,7 @@ class Task(abc.ABC):
|
||||
name=self.DATASET_NAME,
|
||||
data_dir=data_dir,
|
||||
cache_dir=cache_dir,
|
||||
download_mode=download_mode
|
||||
download_mode=download_mode,
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
@@ -473,8 +504,10 @@ class Task(abc.ABC):
|
||||
return rnd.sample(self._training_docs, k)
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
print("Override doc_to_decontamination_query with document specific decontamination query.")
|
||||
assert(False)
|
||||
print(
|
||||
"Override doc_to_decontamination_query with document specific decontamination query."
|
||||
)
|
||||
assert False
|
||||
|
||||
@abstractmethod
|
||||
def doc_to_text(self, doc):
|
||||
@@ -486,22 +519,22 @@ class Task(abc.ABC):
|
||||
|
||||
@abstractmethod
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
@@ -515,7 +548,7 @@ class Task(abc.ABC):
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [metric_score] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metric scores
|
||||
"""
|
||||
pass
|
||||
@@ -524,22 +557,26 @@ class Task(abc.ABC):
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
pass
|
||||
|
||||
def fewshot_description(self):
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"`fewshot_description` will be removed in futures versions. Pass "
|
||||
"any custom descriptions to the `evaluate` function instead.",
|
||||
DeprecationWarning)
|
||||
DeprecationWarning,
|
||||
)
|
||||
return ""
|
||||
|
||||
@utils.positional_deprecated
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
""" Returns a fewshot context string that is made up of a prepended description
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
"""Returns a fewshot context string that is made up of a prepended description
|
||||
(if provided), the `num_fewshot` number of examples, and an appended prompt example.
|
||||
|
||||
:param doc: str
|
||||
@@ -556,7 +593,9 @@ class Task(abc.ABC):
|
||||
:returns: str
|
||||
The fewshot context.
|
||||
"""
|
||||
assert rnd is not None, "A `random.Random` generator argument must be provided to `rnd`"
|
||||
assert (
|
||||
rnd is not None
|
||||
), "A `random.Random` generator argument must be provided to `rnd`"
|
||||
assert not provide_description, (
|
||||
"The `provide_description` arg will be removed in future versions. To prepend "
|
||||
"a custom description to the context, supply the corresponding string via the "
|
||||
@@ -564,7 +603,9 @@ class Task(abc.ABC):
|
||||
)
|
||||
if provide_description is not None:
|
||||
# nudge people to not specify it at all
|
||||
print("WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict")
|
||||
print(
|
||||
"WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict"
|
||||
)
|
||||
|
||||
description = description + "\n\n" if description else ""
|
||||
|
||||
@@ -577,7 +618,9 @@ class Task(abc.ABC):
|
||||
else:
|
||||
if self._fewshot_docs is None:
|
||||
self._fewshot_docs = list(
|
||||
self.validation_docs() if self.has_validation_docs() else self.test_docs()
|
||||
self.validation_docs()
|
||||
if self.has_validation_docs()
|
||||
else self.test_docs()
|
||||
)
|
||||
|
||||
fewshotex = rnd.sample(self._fewshot_docs, num_fewshot + 1)
|
||||
@@ -585,23 +628,27 @@ class Task(abc.ABC):
|
||||
# get rid of the doc that's the one we're evaluating, if it's in the fewshot
|
||||
fewshotex = [x for x in fewshotex if x != doc][:num_fewshot]
|
||||
|
||||
labeled_examples = "\n\n".join(
|
||||
[self.doc_to_text(doc) + self.doc_to_target(doc) for doc in fewshotex]
|
||||
) + "\n\n"
|
||||
labeled_examples = (
|
||||
"\n\n".join(
|
||||
[
|
||||
self.doc_to_text(doc) + self.doc_to_target(doc)
|
||||
for doc in fewshotex
|
||||
]
|
||||
)
|
||||
+ "\n\n"
|
||||
)
|
||||
|
||||
example = self.doc_to_text(doc)
|
||||
return description + labeled_examples + example
|
||||
|
||||
|
||||
class MultipleChoiceTask(Task):
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + doc['choices'][doc['gold']]
|
||||
return " " + doc["choices"][doc["gold"]]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
lls = [
|
||||
rf.loglikelihood(ctx, " {}".format(choice))[0]
|
||||
for choice in doc['choices']
|
||||
rf.loglikelihood(ctx, " {}".format(choice))[0] for choice in doc["choices"]
|
||||
]
|
||||
|
||||
return lls
|
||||
@@ -609,21 +656,21 @@ class MultipleChoiceTask(Task):
|
||||
def process_results(self, doc, results):
|
||||
gold = doc["gold"]
|
||||
|
||||
acc = 1. if np.argmax(results) == gold else 0.
|
||||
acc = 1.0 if np.argmax(results) == gold else 0.0
|
||||
completion_len = np.array([float(len(i)) for i in doc["choices"]])
|
||||
acc_norm = 1. if np.argmax(results / completion_len) == gold else 0.
|
||||
acc_norm = 1.0 if np.argmax(results / completion_len) == gold else 0.0
|
||||
|
||||
return {
|
||||
"acc": acc,
|
||||
"acc_norm": acc_norm,
|
||||
}
|
||||
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True,
|
||||
"acc_norm": True,
|
||||
}
|
||||
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean,
|
||||
@@ -632,7 +679,6 @@ class MultipleChoiceTask(Task):
|
||||
|
||||
|
||||
class PerplexityTask(Task, abc.ABC):
|
||||
|
||||
def should_decontaminate(self):
|
||||
"""Whether this task supports decontamination against model training set."""
|
||||
return True
|
||||
@@ -644,9 +690,15 @@ class PerplexityTask(Task, abc.ABC):
|
||||
assert k == 0
|
||||
return []
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
assert num_fewshot == 0, "The number of fewshot examples must be 0 for perplexity tasks."
|
||||
assert rnd is not None, "A `random.Random` generator argument must be provided to `rnd`."
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert (
|
||||
num_fewshot == 0
|
||||
), "The number of fewshot examples must be 0 for perplexity tasks."
|
||||
assert (
|
||||
rnd is not None
|
||||
), "A `random.Random` generator argument must be provided to `rnd`."
|
||||
assert not provide_description, (
|
||||
"The `provide_description` arg will be removed in future versions. To prepend "
|
||||
"a custom description to the context, supply the corresponding string via the "
|
||||
@@ -654,7 +706,9 @@ class PerplexityTask(Task, abc.ABC):
|
||||
)
|
||||
if provide_description is not None:
|
||||
# nudge people to not specify it at all
|
||||
print("WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict")
|
||||
print(
|
||||
"WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict"
|
||||
)
|
||||
|
||||
return ""
|
||||
|
||||
@@ -680,7 +734,7 @@ class PerplexityTask(Task, abc.ABC):
|
||||
return req
|
||||
|
||||
def process_results(self, doc, results):
|
||||
loglikelihood, = results
|
||||
(loglikelihood,) = results
|
||||
words = self.count_words(doc)
|
||||
bytes_ = self.count_bytes(doc)
|
||||
return {
|
||||
@@ -702,23 +756,23 @@ class PerplexityTask(Task, abc.ABC):
|
||||
|
||||
@classmethod
|
||||
def count_words(cls, doc):
|
||||
""" Downstream tasks with custom word boundaries should override this! """
|
||||
"""Downstream tasks with custom word boundaries should override this!"""
|
||||
return len(re.split(r"\s+", doc))
|
||||
|
||||
|
||||
def hash_args(attr, args):
|
||||
dat = json.dumps([attr] + list(args))
|
||||
return hashlib.sha256(dat.encode('utf-8')).hexdigest()
|
||||
return hashlib.sha256(dat.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
class CacheHook:
|
||||
def __init__(self, cachinglm):
|
||||
if cachinglm is None:
|
||||
if cachinglm is None:
|
||||
self.dbdict = None
|
||||
return
|
||||
|
||||
self.dbdict = cachinglm.dbdict
|
||||
|
||||
|
||||
def add_partial(self, attr, req, res):
|
||||
if self.dbdict is None:
|
||||
return
|
||||
@@ -748,7 +802,7 @@ class CachingLM:
|
||||
def fn(requests):
|
||||
res = []
|
||||
remaining_reqs = []
|
||||
|
||||
|
||||
# figure out which ones are cached and which ones are new
|
||||
for req in requests:
|
||||
hsh = hash_args(attr, req)
|
||||
@@ -761,7 +815,7 @@ class CachingLM:
|
||||
else:
|
||||
res.append(None)
|
||||
remaining_reqs.append(req)
|
||||
|
||||
|
||||
# actually run the LM on the requests that do not have cached results
|
||||
rem_res = getattr(self.lm, attr)(remaining_reqs)
|
||||
|
||||
@@ -779,41 +833,48 @@ class CachingLM:
|
||||
self.dbdict.commit()
|
||||
|
||||
return res
|
||||
|
||||
return fn
|
||||
|
||||
|
||||
def get_cache_hook(self):
|
||||
return CacheHook(self)
|
||||
|
||||
|
||||
REQUEST_RETURN_LENGTHS = {
|
||||
'loglikelihood': 2,
|
||||
'greedy_until': None,
|
||||
'loglikelihood_rolling': None,
|
||||
"loglikelihood": 2,
|
||||
"greedy_until": None,
|
||||
"loglikelihood_rolling": None,
|
||||
}
|
||||
|
||||
|
||||
class Request:
|
||||
def __init__(self, request_type, args, index=None):
|
||||
if request_type not in REQUEST_RETURN_LENGTHS.keys():
|
||||
raise NotImplementedError('The request type {} is not implemented!'.format(request_type))
|
||||
raise NotImplementedError(
|
||||
"The request type {} is not implemented!".format(request_type)
|
||||
)
|
||||
|
||||
self.request_type = request_type
|
||||
self.args = args
|
||||
self.index = index
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
if REQUEST_RETURN_LENGTHS[self.request_type] is None:
|
||||
raise IndexError('This request type does not return multiple arguments!')
|
||||
raise IndexError("This request type does not return multiple arguments!")
|
||||
for i in range(REQUEST_RETURN_LENGTHS[self.request_type]):
|
||||
yield Request(self.request_type, self.args, i)
|
||||
|
||||
|
||||
def __getitem__(self, i):
|
||||
if REQUEST_RETURN_LENGTHS[self.request_type] is None:
|
||||
raise IndexError('This request type does not return multiple arguments!')
|
||||
raise IndexError("This request type does not return multiple arguments!")
|
||||
return Request(self.request_type, self.args, i)
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.request_type == other.request_type and self.args == other.args and self.index == other.index
|
||||
return (
|
||||
self.request_type == other.request_type
|
||||
and self.args == other.args
|
||||
and self.index == other.index
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Req_{self.request_type}{self.args}[{self.index}]\n"
|
||||
@@ -823,6 +884,7 @@ class RequestFactory:
|
||||
def __getattr__(self, attr):
|
||||
def fn(*args):
|
||||
return Request(attr, args)
|
||||
|
||||
return fn
|
||||
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
This directory contains custom EleutherAI datasets not available in the HuggingFace `datasets` hub.
|
||||
|
||||
In the rare case that you need to add a custom dataset to this collection, follow the
|
||||
HuggingFace `datasets` guide found [here](https://huggingface.co/docs/datasets/dataset_script).
|
||||
In the rare case that you need to add a custom dataset to this collection, follow the
|
||||
HuggingFace `datasets` guide found [here](https://huggingface.co/docs/datasets/dataset_script).
|
||||
|
||||
@@ -68,61 +68,111 @@ class Arithmetic(datasets.GeneratorBasedBuilder):
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_2da",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/two_digit_addition.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="2-digit addition",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_2ds",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/two_digit_subtraction.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="2-digit subtraction",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_3da",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/three_digit_addition.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="3-digit addition",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_3ds",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/three_digit_subtraction.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="3-digit subtraction",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_4da",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/four_digit_addition.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="4-digit addition",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_4ds",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/four_digit_subtraction.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="4-digit subtraction",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_5da",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/five_digit_addition.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="5-digit addition",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_5ds",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/five_digit_subtraction.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="5-digit subtraction",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_2dm",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/two_digit_multiplication.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="2-digit multiplication",
|
||||
),
|
||||
ArithmeticConfig(
|
||||
name="arithmetic_1dc",
|
||||
url="https://raw.githubusercontent.com/openai/gpt-3/master/data/single_digit_three_ops.jsonl",
|
||||
features=datasets.Features({"context": datasets.Value("string"), "completion": datasets.Value("string")}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"context": datasets.Value("string"),
|
||||
"completion": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="Single digit 3 operations",
|
||||
),
|
||||
]
|
||||
@@ -155,9 +205,12 @@ class Arithmetic(datasets.GeneratorBasedBuilder):
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
for key, row in enumerate(f):
|
||||
data = json.loads(row)
|
||||
context = data['context'].strip() \
|
||||
.replace('\n\n', '\n') \
|
||||
.replace('Q:', 'Question:') \
|
||||
.replace('A:', 'Answer:')
|
||||
completion = data['completion']
|
||||
yield key, {'context': context, 'completion': completion}
|
||||
context = (
|
||||
data["context"]
|
||||
.strip()
|
||||
.replace("\n\n", "\n")
|
||||
.replace("Q:", "Question:")
|
||||
.replace("A:", "Answer:")
|
||||
)
|
||||
completion = data["completion"]
|
||||
yield key, {"context": context, "completion": completion}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -50,13 +50,16 @@ _URLS = "https://github.com/chaochun/nlu-asdiv-dataset/archive/55790e5270bb91ccf
|
||||
|
||||
|
||||
class ASDiv(datasets.GeneratorBasedBuilder):
|
||||
""" ASDiv: A Diverse Corpus for Evaluating and Developing English Math Word Problem Solvers """
|
||||
"""ASDiv: A Diverse Corpus for Evaluating and Developing English Math Word Problem Solvers"""
|
||||
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="asdiv", version=VERSION,
|
||||
description="A diverse corpus for evaluating and developing english math word problem solvers")
|
||||
datasets.BuilderConfig(
|
||||
name="asdiv",
|
||||
version=VERSION,
|
||||
description="A diverse corpus for evaluating and developing english math word problem solvers",
|
||||
)
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -86,7 +89,9 @@ class ASDiv(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.VALIDATION,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": os.path.join(data_dir, base_filepath, "dataset", "ASDiv.xml"),
|
||||
"filepath": os.path.join(
|
||||
data_dir, base_filepath, "dataset", "ASDiv.xml"
|
||||
),
|
||||
"split": datasets.Split.VALIDATION,
|
||||
},
|
||||
),
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"asdiv": {"description": "ASDiv (Academia Sinica Diverse MWP Dataset) is a diverse (in terms of both language\npatterns and problem types) English math word problem (MWP) corpus for evaluating\nthe capability of various MWP solvers. Existing MWP corpora for studying AI progress\nremain limited either in language usage patterns or in problem types. We thus present\na new English MWP corpus with 2,305 MWPs that cover more text patterns and most problem\ntypes taught in elementary school. Each MWP is annotated with its problem type and grade\nlevel (for indicating the level of difficulty).\n", "citation": "@misc{miao2021diverse,\n title={A Diverse Corpus for Evaluating and Developing English Math Word Problem Solvers},\n author={Shen-Yun Miao and Chao-Chun Liang and Keh-Yih Su},\n year={2021},\n eprint={2106.15772},\n archivePrefix={arXiv},\n primaryClass={cs.AI}\n}\n", "homepage": "https://github.com/chaochun/nlu-asdiv-dataset", "license": "", "features": {"body": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "solution_type": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}, "formula": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "as_div", "config_name": "asdiv", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 501489, "num_examples": 2305, "dataset_name": "as_div"}}, "download_checksums": {"https://github.com/chaochun/nlu-asdiv-dataset/archive/55790e5270bb91ccfa5053194b25732534696b50.zip": {"num_bytes": 440966, "checksum": "8f1fe4f6d5f170ec1e24ab78c244153c14c568b1bb2b1dad0324e71f37939a2d"}}, "download_size": 440966, "post_processing_size": null, "dataset_size": 501489, "size_in_bytes": 942455}}
|
||||
{"asdiv": {"description": "ASDiv (Academia Sinica Diverse MWP Dataset) is a diverse (in terms of both language\npatterns and problem types) English math word problem (MWP) corpus for evaluating\nthe capability of various MWP solvers. Existing MWP corpora for studying AI progress\nremain limited either in language usage patterns or in problem types. We thus present\na new English MWP corpus with 2,305 MWPs that cover more text patterns and most problem\ntypes taught in elementary school. Each MWP is annotated with its problem type and grade\nlevel (for indicating the level of difficulty).\n", "citation": "@misc{miao2021diverse,\n title={A Diverse Corpus for Evaluating and Developing English Math Word Problem Solvers},\n author={Shen-Yun Miao and Chao-Chun Liang and Keh-Yih Su},\n year={2021},\n eprint={2106.15772},\n archivePrefix={arXiv},\n primaryClass={cs.AI}\n}\n", "homepage": "https://github.com/chaochun/nlu-asdiv-dataset", "license": "", "features": {"body": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "solution_type": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}, "formula": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "as_div", "config_name": "asdiv", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 501489, "num_examples": 2305, "dataset_name": "as_div"}}, "download_checksums": {"https://github.com/chaochun/nlu-asdiv-dataset/archive/55790e5270bb91ccfa5053194b25732534696b50.zip": {"num_bytes": 440966, "checksum": "8f1fe4f6d5f170ec1e24ab78c244153c14c568b1bb2b1dad0324e71f37939a2d"}}, "download_size": 440966, "post_processing_size": null, "dataset_size": 501489, "size_in_bytes": 942455}}
|
||||
|
||||
@@ -61,7 +61,7 @@ _EMPTY_ADDITIONAL_ANSWER = {
|
||||
"span_end": -1,
|
||||
"span_text": "",
|
||||
"input_text": "",
|
||||
"turn_id": -1
|
||||
"turn_id": -1,
|
||||
}
|
||||
],
|
||||
"1": [
|
||||
@@ -70,7 +70,7 @@ _EMPTY_ADDITIONAL_ANSWER = {
|
||||
"span_end": -1,
|
||||
"span_text": "",
|
||||
"input_text": "",
|
||||
"turn_id": -1
|
||||
"turn_id": -1,
|
||||
}
|
||||
],
|
||||
"2": [
|
||||
@@ -79,7 +79,7 @@ _EMPTY_ADDITIONAL_ANSWER = {
|
||||
"span_end": -1,
|
||||
"span_text": "",
|
||||
"input_text": "",
|
||||
"turn_id": -1
|
||||
"turn_id": -1,
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -91,8 +91,9 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="coqa", version=VERSION,
|
||||
description="The CoQA dataset."),
|
||||
datasets.BuilderConfig(
|
||||
name="coqa", version=VERSION, description="The CoQA dataset."
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -101,41 +102,52 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"id": datasets.Value("string"),
|
||||
"source": datasets.Value("string"),
|
||||
"story": datasets.Value("string"),
|
||||
"questions": datasets.features.Sequence({
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}),
|
||||
"answers": datasets.features.Sequence({
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}),
|
||||
"questions": datasets.features.Sequence(
|
||||
{
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}
|
||||
),
|
||||
"answers": datasets.features.Sequence(
|
||||
{
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}
|
||||
),
|
||||
"additional_answers": {
|
||||
"0": datasets.features.Sequence({
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}),
|
||||
"1": datasets.features.Sequence({
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}),
|
||||
"2": datasets.features.Sequence({
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}),
|
||||
}
|
||||
})
|
||||
"0": datasets.features.Sequence(
|
||||
{
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}
|
||||
),
|
||||
"1": datasets.features.Sequence(
|
||||
{
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}
|
||||
),
|
||||
"2": datasets.features.Sequence(
|
||||
{
|
||||
"span_start": datasets.Value("int32"),
|
||||
"span_end": datasets.Value("int32"),
|
||||
"span_text": datasets.Value("string"),
|
||||
"input_text": datasets.Value("string"),
|
||||
"turn_id": datasets.Value("int32"),
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
return datasets.DatasetInfo(
|
||||
description=_DESCRIPTION,
|
||||
features=features,
|
||||
@@ -175,10 +187,7 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
source = row["source"]
|
||||
story = row["story"]
|
||||
questions = [
|
||||
{
|
||||
"input_text": q["input_text"],
|
||||
"turn_id": q["turn_id"]
|
||||
}
|
||||
{"input_text": q["input_text"], "turn_id": q["turn_id"]}
|
||||
for q in row["questions"]
|
||||
]
|
||||
answers = [
|
||||
@@ -187,7 +196,7 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"span_end": a["span_end"],
|
||||
"span_text": a["span_text"],
|
||||
"input_text": a["input_text"],
|
||||
"turn_id": a["turn_id"]
|
||||
"turn_id": a["turn_id"],
|
||||
}
|
||||
for a in row["answers"]
|
||||
]
|
||||
@@ -201,7 +210,7 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"span_end": a0["span_end"],
|
||||
"span_text": a0["span_text"],
|
||||
"input_text": a0["input_text"],
|
||||
"turn_id": a0["turn_id"]
|
||||
"turn_id": a0["turn_id"],
|
||||
}
|
||||
for a0 in row["additional_answers"]["0"]
|
||||
],
|
||||
@@ -211,7 +220,7 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"span_end": a1["span_end"],
|
||||
"span_text": a1["span_text"],
|
||||
"input_text": a1["input_text"],
|
||||
"turn_id": a1["turn_id"]
|
||||
"turn_id": a1["turn_id"],
|
||||
}
|
||||
for a1 in row["additional_answers"]["1"]
|
||||
],
|
||||
@@ -221,7 +230,7 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"span_end": a2["span_end"],
|
||||
"span_text": a2["span_text"],
|
||||
"input_text": a2["input_text"],
|
||||
"turn_id": a2["turn_id"]
|
||||
"turn_id": a2["turn_id"],
|
||||
}
|
||||
for a2 in row["additional_answers"]["2"]
|
||||
],
|
||||
@@ -232,5 +241,5 @@ class Coqa(datasets.GeneratorBasedBuilder):
|
||||
"source": source,
|
||||
"questions": questions,
|
||||
"answers": answers,
|
||||
"additional_answers": additional_answers
|
||||
"additional_answers": additional_answers,
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"coqa": {"description": "CoQA is a large-scale dataset for building Conversational Question Answering\nsystems. The goal of the CoQA challenge is to measure the ability of machines to\nunderstand a text passage and answer a series of interconnected questions that\nappear in a conversation.\n", "citation": "@misc{reddy2018coqa,\n title={CoQA: A Conversational Question Answering Challenge},\n author={Siva Reddy and Danqi Chen and Christopher D. Manning},\n year={2018},\n eprint={1808.07042},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://stanfordnlp.github.io/coqa/", "license": "", "features": {"id": {"dtype": "string", "id": null, "_type": "Value"}, "source": {"dtype": "string", "id": null, "_type": "Value"}, "story": {"dtype": "string", "id": null, "_type": "Value"}, "questions": {"feature": {"input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "answers": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "additional_answers": {"0": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "1": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "2": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "coqa", "config_name": "coqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 26250528, "num_examples": 7199, "dataset_name": "coqa"}, "validation": {"name": "validation", "num_bytes": 3765933, "num_examples": 500, "dataset_name": "coqa"}}, "download_checksums": {"https://nlp.stanford.edu/data/coqa/coqa-train-v1.0.json": {"num_bytes": 49001836, "checksum": "b0fdb2bc1bd38dd3ca2ce5fa2ac3e02c6288ac914f241ac409a655ffb6619fa6"}, "https://nlp.stanford.edu/data/coqa/coqa-dev-v1.0.json": {"num_bytes": 9090845, "checksum": "dfa367a9733ce53222918d0231d9b3bedc2b8ee831a2845f62dfc70701f2540a"}}, "download_size": 58092681, "post_processing_size": null, "dataset_size": 30016461, "size_in_bytes": 88109142}}
|
||||
{"coqa": {"description": "CoQA is a large-scale dataset for building Conversational Question Answering\nsystems. The goal of the CoQA challenge is to measure the ability of machines to\nunderstand a text passage and answer a series of interconnected questions that\nappear in a conversation.\n", "citation": "@misc{reddy2018coqa,\n title={CoQA: A Conversational Question Answering Challenge},\n author={Siva Reddy and Danqi Chen and Christopher D. Manning},\n year={2018},\n eprint={1808.07042},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://stanfordnlp.github.io/coqa/", "license": "", "features": {"id": {"dtype": "string", "id": null, "_type": "Value"}, "source": {"dtype": "string", "id": null, "_type": "Value"}, "story": {"dtype": "string", "id": null, "_type": "Value"}, "questions": {"feature": {"input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "answers": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "additional_answers": {"0": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "1": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}, "2": {"feature": {"span_start": {"dtype": "int32", "id": null, "_type": "Value"}, "span_end": {"dtype": "int32", "id": null, "_type": "Value"}, "span_text": {"dtype": "string", "id": null, "_type": "Value"}, "input_text": {"dtype": "string", "id": null, "_type": "Value"}, "turn_id": {"dtype": "int32", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "coqa", "config_name": "coqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 26250528, "num_examples": 7199, "dataset_name": "coqa"}, "validation": {"name": "validation", "num_bytes": 3765933, "num_examples": 500, "dataset_name": "coqa"}}, "download_checksums": {"https://nlp.stanford.edu/data/coqa/coqa-train-v1.0.json": {"num_bytes": 49001836, "checksum": "b0fdb2bc1bd38dd3ca2ce5fa2ac3e02c6288ac914f241ac409a655ffb6619fa6"}, "https://nlp.stanford.edu/data/coqa/coqa-dev-v1.0.json": {"num_bytes": 9090845, "checksum": "dfa367a9733ce53222918d0231d9b3bedc2b8ee831a2845f62dfc70701f2540a"}}, "download_size": 58092681, "post_processing_size": null, "dataset_size": 30016461, "size_in_bytes": 88109142}}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"drop": {"description": "DROP is a QA dataset which tests comprehensive understanding of paragraphs. In \nthis crowdsourced, adversarially-created, 96k question-answering benchmark, a \nsystem must resolve multiple references in a question, map them onto a paragraph,\nand perform discrete operations over them (such as addition, counting, or sorting).\n", "citation": "@misc{dua2019drop,\n title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs}, \n author={Dheeru Dua and Yizhong Wang and Pradeep Dasigi and Gabriel Stanovsky and Sameer Singh and Matt Gardner},\n year={2019},\n eprint={1903.00161},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://allenai.org/data/drop", "license": "", "features": {"section_id": {"dtype": "string", "id": null, "_type": "Value"}, "passage": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "query_id": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"number": {"dtype": "string", "id": null, "_type": "Value"}, "date": {"day": {"dtype": "string", "id": null, "_type": "Value"}, "month": {"dtype": "string", "id": null, "_type": "Value"}, "year": {"dtype": "string", "id": null, "_type": "Value"}}, "spans": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "worker_id": {"dtype": "string", "id": null, "_type": "Value"}, "hit_id": {"dtype": "string", "id": null, "_type": "Value"}}, "validated_answers": {"feature": {"number": {"dtype": "string", "id": null, "_type": "Value"}, "date": {"day": {"dtype": "string", "id": null, "_type": "Value"}, "month": {"dtype": "string", "id": null, "_type": "Value"}, "year": {"dtype": "string", "id": null, "_type": "Value"}}, "spans": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "worker_id": {"dtype": "string", "id": null, "_type": "Value"}, "hit_id": {"dtype": "string", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "drop", "config_name": "drop", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 108858121, "num_examples": 77409, "dataset_name": "drop"}, "validation": {"name": "validation", "num_bytes": 12560739, "num_examples": 9536, "dataset_name": "drop"}}, "download_checksums": {"https://s3-us-west-2.amazonaws.com/allennlp/datasets/drop/drop_dataset.zip": {"num_bytes": 8308692, "checksum": "39d2278a29fd729de301b111a45f434c24834f40df8f4ff116d864589e3249d6"}}, "download_size": 8308692, "post_processing_size": null, "dataset_size": 121418860, "size_in_bytes": 129727552}}
|
||||
{"drop": {"description": "DROP is a QA dataset which tests comprehensive understanding of paragraphs. In \nthis crowdsourced, adversarially-created, 96k question-answering benchmark, a \nsystem must resolve multiple references in a question, map them onto a paragraph,\nand perform discrete operations over them (such as addition, counting, or sorting).\n", "citation": "@misc{dua2019drop,\n title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs}, \n author={Dheeru Dua and Yizhong Wang and Pradeep Dasigi and Gabriel Stanovsky and Sameer Singh and Matt Gardner},\n year={2019},\n eprint={1903.00161},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://allenai.org/data/drop", "license": "", "features": {"section_id": {"dtype": "string", "id": null, "_type": "Value"}, "passage": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "query_id": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"number": {"dtype": "string", "id": null, "_type": "Value"}, "date": {"day": {"dtype": "string", "id": null, "_type": "Value"}, "month": {"dtype": "string", "id": null, "_type": "Value"}, "year": {"dtype": "string", "id": null, "_type": "Value"}}, "spans": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "worker_id": {"dtype": "string", "id": null, "_type": "Value"}, "hit_id": {"dtype": "string", "id": null, "_type": "Value"}}, "validated_answers": {"feature": {"number": {"dtype": "string", "id": null, "_type": "Value"}, "date": {"day": {"dtype": "string", "id": null, "_type": "Value"}, "month": {"dtype": "string", "id": null, "_type": "Value"}, "year": {"dtype": "string", "id": null, "_type": "Value"}}, "spans": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "worker_id": {"dtype": "string", "id": null, "_type": "Value"}, "hit_id": {"dtype": "string", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "drop", "config_name": "drop", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 108858121, "num_examples": 77409, "dataset_name": "drop"}, "validation": {"name": "validation", "num_bytes": 12560739, "num_examples": 9536, "dataset_name": "drop"}}, "download_checksums": {"https://s3-us-west-2.amazonaws.com/allennlp/datasets/drop/drop_dataset.zip": {"num_bytes": 8308692, "checksum": "39d2278a29fd729de301b111a45f434c24834f40df8f4ff116d864589e3249d6"}}, "download_size": 8308692, "post_processing_size": null, "dataset_size": 121418860, "size_in_bytes": 129727552}}
|
||||
|
||||
@@ -25,7 +25,7 @@ import datasets
|
||||
|
||||
_CITATION = """\
|
||||
@misc{dua2019drop,
|
||||
title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs},
|
||||
title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs},
|
||||
author={Dheeru Dua and Yizhong Wang and Pradeep Dasigi and Gabriel Stanovsky and Sameer Singh and Matt Gardner},
|
||||
year={2019},
|
||||
eprint={1903.00161},
|
||||
@@ -35,8 +35,8 @@ _CITATION = """\
|
||||
"""
|
||||
|
||||
_DESCRIPTION = """\
|
||||
DROP is a QA dataset which tests comprehensive understanding of paragraphs. In
|
||||
this crowdsourced, adversarially-created, 96k question-answering benchmark, a
|
||||
DROP is a QA dataset which tests comprehensive understanding of paragraphs. In
|
||||
this crowdsourced, adversarially-created, 96k question-answering benchmark, a
|
||||
system must resolve multiple references in a question, map them onto a paragraph,
|
||||
and perform discrete operations over them (such as addition, counting, or sorting).
|
||||
"""
|
||||
@@ -50,17 +50,19 @@ _URLS = {
|
||||
"drop": "https://s3-us-west-2.amazonaws.com/allennlp/datasets/drop/drop_dataset.zip",
|
||||
}
|
||||
|
||||
_EMPTY_VALIDATED_ANSWER = [{
|
||||
"number": "",
|
||||
"date": {
|
||||
"day": "",
|
||||
"month": "",
|
||||
"year": "",
|
||||
},
|
||||
"spans": [],
|
||||
"worker_id": "",
|
||||
"hit_id": ""
|
||||
}]
|
||||
_EMPTY_VALIDATED_ANSWER = [
|
||||
{
|
||||
"number": "",
|
||||
"date": {
|
||||
"day": "",
|
||||
"month": "",
|
||||
"year": "",
|
||||
},
|
||||
"spans": [],
|
||||
"worker_id": "",
|
||||
"hit_id": "",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Drop(datasets.GeneratorBasedBuilder):
|
||||
@@ -69,39 +71,44 @@ class Drop(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="drop", version=VERSION,
|
||||
description="The DROP dataset."),
|
||||
datasets.BuilderConfig(
|
||||
name="drop", version=VERSION, description="The DROP dataset."
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
features = datasets.Features({
|
||||
"section_id": datasets.Value("string"),
|
||||
"passage": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"query_id": datasets.Value("string"),
|
||||
"answer": {
|
||||
"number": datasets.Value("string"),
|
||||
"date": {
|
||||
"day": datasets.Value("string"),
|
||||
"month": datasets.Value("string"),
|
||||
"year": datasets.Value("string"),
|
||||
features = datasets.Features(
|
||||
{
|
||||
"section_id": datasets.Value("string"),
|
||||
"passage": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"query_id": datasets.Value("string"),
|
||||
"answer": {
|
||||
"number": datasets.Value("string"),
|
||||
"date": {
|
||||
"day": datasets.Value("string"),
|
||||
"month": datasets.Value("string"),
|
||||
"year": datasets.Value("string"),
|
||||
},
|
||||
"spans": datasets.features.Sequence(datasets.Value("string")),
|
||||
"worker_id": datasets.Value("string"),
|
||||
"hit_id": datasets.Value("string"),
|
||||
},
|
||||
"spans": datasets.features.Sequence(datasets.Value("string")),
|
||||
"worker_id": datasets.Value("string"),
|
||||
"hit_id": datasets.Value("string"),
|
||||
},
|
||||
"validated_answers": datasets.features.Sequence({
|
||||
"number": datasets.Value("string"),
|
||||
"date": {
|
||||
"day": datasets.Value("string"),
|
||||
"month": datasets.Value("string"),
|
||||
"year": datasets.Value("string"),
|
||||
},
|
||||
"spans": datasets.features.Sequence(datasets.Value("string")),
|
||||
"worker_id": datasets.Value("string"),
|
||||
"hit_id": datasets.Value("string"),
|
||||
}),
|
||||
})
|
||||
"validated_answers": datasets.features.Sequence(
|
||||
{
|
||||
"number": datasets.Value("string"),
|
||||
"date": {
|
||||
"day": datasets.Value("string"),
|
||||
"month": datasets.Value("string"),
|
||||
"year": datasets.Value("string"),
|
||||
},
|
||||
"spans": datasets.features.Sequence(datasets.Value("string")),
|
||||
"worker_id": datasets.Value("string"),
|
||||
"hit_id": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
return datasets.DatasetInfo(
|
||||
description=_DESCRIPTION,
|
||||
features=features,
|
||||
@@ -118,7 +125,9 @@ class Drop(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TRAIN,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": os.path.join(data_dir, "drop_dataset", "drop_dataset_train.json"),
|
||||
"filepath": os.path.join(
|
||||
data_dir, "drop_dataset", "drop_dataset_train.json"
|
||||
),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
@@ -126,7 +135,9 @@ class Drop(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.VALIDATION,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": os.path.join(data_dir, "drop_dataset", "drop_dataset_dev.json"),
|
||||
"filepath": os.path.join(
|
||||
data_dir, "drop_dataset", "drop_dataset_dev.json"
|
||||
),
|
||||
"split": "validation",
|
||||
},
|
||||
),
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"gsm8k": {"description": "State-of-the-art language models can match human performance on many tasks, but \nthey still struggle to robustly perform multi-step mathematical reasoning. To \ndiagnose the failures of current models and support research, we introduce GSM8K,\na dataset of 8.5K high quality linguistically diverse grade school math word problems.\nWe find that even the largest transformer models fail to achieve high test performance, \ndespite the conceptual simplicity of this problem distribution.\n", "citation": "@misc{cobbe2021training,\n title={Training Verifiers to Solve Math Word Problems},\n author={Karl Cobbe and Vineet Kosaraju and Mohammad Bavarian and Jacob Hilton and Reiichiro Nakano and Christopher Hesse and John Schulman},\n year={2021},\n eprint={2110.14168},\n archivePrefix={arXiv},\n primaryClass={cs.LG}\n}\n", "homepage": "https://github.com/openai/grade-school-math", "license": "", "features": {"question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "gsm8_k", "config_name": "gsm8k", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 3963202, "num_examples": 7473, "dataset_name": "gsm8_k"}, "test": {"name": "test", "num_bytes": 713732, "num_examples": 1319, "dataset_name": "gsm8_k"}}, "download_checksums": {"https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/train.jsonl": {"num_bytes": 4166206, "checksum": "17f347dc51477c50d4efb83959dbb7c56297aba886e5544ee2aaed3024813465"}, "https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/test.jsonl": {"num_bytes": 749738, "checksum": "3730d312f6e3440559ace48831e51066acaca737f6eabec99bccb9e4b3c39d14"}}, "download_size": 4915944, "post_processing_size": null, "dataset_size": 4676934, "size_in_bytes": 9592878}}
|
||||
{"gsm8k": {"description": "State-of-the-art language models can match human performance on many tasks, but \nthey still struggle to robustly perform multi-step mathematical reasoning. To \ndiagnose the failures of current models and support research, we introduce GSM8K,\na dataset of 8.5K high quality linguistically diverse grade school math word problems.\nWe find that even the largest transformer models fail to achieve high test performance, \ndespite the conceptual simplicity of this problem distribution.\n", "citation": "@misc{cobbe2021training,\n title={Training Verifiers to Solve Math Word Problems},\n author={Karl Cobbe and Vineet Kosaraju and Mohammad Bavarian and Jacob Hilton and Reiichiro Nakano and Christopher Hesse and John Schulman},\n year={2021},\n eprint={2110.14168},\n archivePrefix={arXiv},\n primaryClass={cs.LG}\n}\n", "homepage": "https://github.com/openai/grade-school-math", "license": "", "features": {"question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "gsm8_k", "config_name": "gsm8k", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 3963202, "num_examples": 7473, "dataset_name": "gsm8_k"}, "test": {"name": "test", "num_bytes": 713732, "num_examples": 1319, "dataset_name": "gsm8_k"}}, "download_checksums": {"https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/train.jsonl": {"num_bytes": 4166206, "checksum": "17f347dc51477c50d4efb83959dbb7c56297aba886e5544ee2aaed3024813465"}, "https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/test.jsonl": {"num_bytes": 749738, "checksum": "3730d312f6e3440559ace48831e51066acaca737f6eabec99bccb9e4b3c39d14"}}, "download_size": 4915944, "post_processing_size": null, "dataset_size": 4676934, "size_in_bytes": 9592878}}
|
||||
|
||||
@@ -31,11 +31,11 @@ _CITATION = """\
|
||||
"""
|
||||
|
||||
_DESCRIPTION = """\
|
||||
State-of-the-art language models can match human performance on many tasks, but
|
||||
they still struggle to robustly perform multi-step mathematical reasoning. To
|
||||
State-of-the-art language models can match human performance on many tasks, but
|
||||
they still struggle to robustly perform multi-step mathematical reasoning. To
|
||||
diagnose the failures of current models and support research, we introduce GSM8K,
|
||||
a dataset of 8.5K high quality linguistically diverse grade school math word problems.
|
||||
We find that even the largest transformer models fail to achieve high test performance,
|
||||
We find that even the largest transformer models fail to achieve high test performance,
|
||||
despite the conceptual simplicity of this problem distribution.
|
||||
"""
|
||||
|
||||
@@ -56,8 +56,11 @@ class GSM8K(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="gsm8k", version=VERSION,
|
||||
description="The Grade School Math 8k dataset."),
|
||||
datasets.BuilderConfig(
|
||||
name="gsm8k",
|
||||
version=VERSION,
|
||||
description="The Grade School Math 8k dataset.",
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -90,10 +93,7 @@ class GSM8K(datasets.GeneratorBasedBuilder):
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": data_dir["test"],
|
||||
"split": "test"
|
||||
},
|
||||
gen_kwargs={"filepath": data_dir["test"], "split": "test"},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,3 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2020 The HuggingFace Datasets Authors and the current dataset script contributor.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
# NOTE: This is an exact copy of
|
||||
# https://github.com/huggingface/datasets/blob/3804442bb7cfcb9d52044d92688115cfdc69c2da/datasets/head_qa/head_qa.py
|
||||
# https://github.com/huggingface/datasets/blob/3804442bb7cfcb9d52044d92688115cfdc69c2da/datasets/head_qa/head_qa.py
|
||||
# with the exception of the `image` feature. This is to avoid adding `Pillow`
|
||||
# as a dependency.
|
||||
"""HEAD-QA: A Healthcare Dataset for Complex Reasoning."""
|
||||
@@ -65,8 +64,12 @@ class HeadQA(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("1.1.0")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="es", version=VERSION, description="Spanish HEAD dataset"),
|
||||
datasets.BuilderConfig(name="en", version=VERSION, description="English HEAD dataset"),
|
||||
datasets.BuilderConfig(
|
||||
name="es", version=VERSION, description="Spanish HEAD dataset"
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="en", version=VERSION, description="English HEAD dataset"
|
||||
),
|
||||
]
|
||||
|
||||
DEFAULT_CONFIG_NAME = "es"
|
||||
@@ -106,15 +109,24 @@ class HeadQA(datasets.GeneratorBasedBuilder):
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TRAIN,
|
||||
gen_kwargs={"data_dir": data_dir, "filepath": os.path.join(data_lang_dir, f"train_{dir}.json")},
|
||||
gen_kwargs={
|
||||
"data_dir": data_dir,
|
||||
"filepath": os.path.join(data_lang_dir, f"train_{dir}.json"),
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
gen_kwargs={"data_dir": data_dir, "filepath": os.path.join(data_lang_dir, f"test_{dir}.json")},
|
||||
gen_kwargs={
|
||||
"data_dir": data_dir,
|
||||
"filepath": os.path.join(data_lang_dir, f"test_{dir}.json"),
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
gen_kwargs={"data_dir": data_dir, "filepath": os.path.join(data_lang_dir, f"dev_{dir}.json")},
|
||||
gen_kwargs={
|
||||
"data_dir": data_dir,
|
||||
"filepath": os.path.join(data_lang_dir, f"dev_{dir}.json"),
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -134,7 +146,9 @@ class HeadQA(datasets.GeneratorBasedBuilder):
|
||||
|
||||
aids = [answer["aid"] for answer in question["answers"]]
|
||||
atexts = [answer["atext"].strip() for answer in question["answers"]]
|
||||
answers = [{"aid": aid, "atext": atext} for aid, atext in zip(aids, atexts)]
|
||||
answers = [
|
||||
{"aid": aid, "atext": atext} for aid, atext in zip(aids, atexts)
|
||||
]
|
||||
|
||||
id_ = f"{exam_id}_{qid}"
|
||||
yield id_, {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,54 +71,64 @@ class HendrycksEthics(datasets.GeneratorBasedBuilder):
|
||||
EthicsConfig(
|
||||
name="commonsense",
|
||||
prefix="cm",
|
||||
features=datasets.Features({
|
||||
"label": datasets.Value("int32"),
|
||||
"input": datasets.Value("string"),
|
||||
"is_short": datasets.Value("bool"),
|
||||
"edited": datasets.Value("bool"),
|
||||
}),
|
||||
description="The Commonsense subset contains examples focusing on moral standards and principles that most people intuitively accept."
|
||||
features=datasets.Features(
|
||||
{
|
||||
"label": datasets.Value("int32"),
|
||||
"input": datasets.Value("string"),
|
||||
"is_short": datasets.Value("bool"),
|
||||
"edited": datasets.Value("bool"),
|
||||
}
|
||||
),
|
||||
description="The Commonsense subset contains examples focusing on moral standards and principles that most people intuitively accept.",
|
||||
),
|
||||
EthicsConfig(
|
||||
name="deontology",
|
||||
prefix="deontology",
|
||||
features=datasets.Features({
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
"excuse": datasets.Value("string"),
|
||||
}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
"excuse": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="The Deontology subset contains examples focusing on whether an act is required, permitted, or forbidden according to a set of rules or constraints",
|
||||
),
|
||||
EthicsConfig(
|
||||
name="justice",
|
||||
prefix="justice",
|
||||
features=datasets.Features({
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="The Justice subset contains examples focusing on how a character treats another person",
|
||||
),
|
||||
EthicsConfig(
|
||||
name="utilitarianism",
|
||||
prefix="util",
|
||||
features=datasets.Features({
|
||||
"activity": datasets.Value("string"),
|
||||
"baseline": datasets.Value("string"),
|
||||
"rating": datasets.Value("string"), # Empty rating.
|
||||
}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"activity": datasets.Value("string"),
|
||||
"baseline": datasets.Value("string"),
|
||||
"rating": datasets.Value("string"), # Empty rating.
|
||||
}
|
||||
),
|
||||
description="The Utilitarianism subset contains scenarios that should be ranked from most pleasant to least pleasant for the person in the scenario",
|
||||
),
|
||||
EthicsConfig(
|
||||
name="virtue",
|
||||
prefix="virtue",
|
||||
features=datasets.Features({
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
"trait": datasets.Value("string"),
|
||||
}),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"group_id": datasets.Value("int32"),
|
||||
"label": datasets.Value("int32"),
|
||||
"scenario": datasets.Value("string"),
|
||||
"trait": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="The Virtue subset contains scenarios focusing on whether virtues or vices are being exemplified",
|
||||
),
|
||||
]
|
||||
@@ -140,7 +150,12 @@ class HendrycksEthics(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TRAIN,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": os.path.join(data_dir, "ethics", self.config.name, f"{self.config.prefix}_train.csv"),
|
||||
"filepath": os.path.join(
|
||||
data_dir,
|
||||
"ethics",
|
||||
self.config.name,
|
||||
f"{self.config.prefix}_train.csv",
|
||||
),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
@@ -148,18 +163,22 @@ class HendrycksEthics(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": os.path.join(data_dir, "ethics", self.config.name, f"{self.config.prefix}_test.csv"),
|
||||
"split": "test"
|
||||
"filepath": os.path.join(
|
||||
data_dir,
|
||||
"ethics",
|
||||
self.config.name,
|
||||
f"{self.config.prefix}_test.csv",
|
||||
),
|
||||
"split": "test",
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
|
||||
# method parameters are unpacked from `gen_kwargs` as given in `_split_generators`
|
||||
def _generate_examples(self, filepath, split):
|
||||
with open(filepath, newline='') as f:
|
||||
with open(filepath, newline="") as f:
|
||||
if self.config.name == "utilitarianism":
|
||||
contents = csv.DictReader(
|
||||
f, fieldnames=['activity', "baseline"])
|
||||
contents = csv.DictReader(f, fieldnames=["activity", "baseline"])
|
||||
else:
|
||||
contents = csv.DictReader(f)
|
||||
# For subsets with grouped scenarios, tag them with an id.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -44,13 +44,13 @@ _LICENSE = ""
|
||||
_URLS = "https://people.eecs.berkeley.edu/~hendrycks/MATH.tar"
|
||||
|
||||
_NAMES = [
|
||||
'algebra',
|
||||
'counting_and_probability',
|
||||
'geometry',
|
||||
'intermediate_algebra',
|
||||
'number_theory',
|
||||
'prealgebra',
|
||||
'precalculus',
|
||||
"algebra",
|
||||
"counting_and_probability",
|
||||
"geometry",
|
||||
"intermediate_algebra",
|
||||
"number_theory",
|
||||
"prealgebra",
|
||||
"precalculus",
|
||||
]
|
||||
|
||||
|
||||
@@ -89,7 +89,9 @@ class HendrycksMath(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TRAIN,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"basepath": os.path.join(data_dir, "MATH", "train", self.config.name),
|
||||
"basepath": os.path.join(
|
||||
data_dir, "MATH", "train", self.config.name
|
||||
),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
@@ -97,8 +99,10 @@ class HendrycksMath(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"basepath": os.path.join(data_dir, "MATH", "test", self.config.name),
|
||||
"split": "test"
|
||||
"basepath": os.path.join(
|
||||
data_dir, "MATH", "test", self.config.name
|
||||
),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -107,7 +111,7 @@ class HendrycksMath(datasets.GeneratorBasedBuilder):
|
||||
def _generate_examples(self, basepath, split):
|
||||
key = 0
|
||||
for file in sorted(pathlib.Path(basepath).iterdir()):
|
||||
with open(file, "r", encoding='utf-8') as f:
|
||||
with open(file, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
yield key, {
|
||||
"problem": data["problem"],
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -22,7 +22,7 @@ import datasets
|
||||
|
||||
_CITATION = """\
|
||||
@misc{
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
title={The LAMBADA dataset},
|
||||
DOI={10.5281/zenodo.2630551},
|
||||
publisher={Zenodo},
|
||||
@@ -62,12 +62,34 @@ class Lambada(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="original", version=VERSION, description="The LAMBADA dataset"),
|
||||
datasets.BuilderConfig(name="en", version=VERSION, description="The English translated LAMBADA dataset"),
|
||||
datasets.BuilderConfig(name="fr", version=VERSION, description="The French translated LAMBADA dataset"),
|
||||
datasets.BuilderConfig(name="de", version=VERSION, description="The German translated LAMBADA dataset"),
|
||||
datasets.BuilderConfig(name="it", version=VERSION, description="The Italian translated LAMBADA dataset"),
|
||||
datasets.BuilderConfig(name="es", version=VERSION, description="The Spanish translated LAMBADA dataset"),
|
||||
datasets.BuilderConfig(
|
||||
name="original", version=VERSION, description="The LAMBADA dataset"
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="en",
|
||||
version=VERSION,
|
||||
description="The English translated LAMBADA dataset",
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="fr",
|
||||
version=VERSION,
|
||||
description="The French translated LAMBADA dataset",
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="de",
|
||||
version=VERSION,
|
||||
description="The German translated LAMBADA dataset",
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="it",
|
||||
version=VERSION,
|
||||
description="The Italian translated LAMBADA dataset",
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="es",
|
||||
version=VERSION,
|
||||
description="The Spanish translated LAMBADA dataset",
|
||||
),
|
||||
]
|
||||
|
||||
DEFAULT_CONFIG_NAME = "original"
|
||||
@@ -105,6 +127,4 @@ class Lambada(datasets.GeneratorBasedBuilder):
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
for key, row in enumerate(f):
|
||||
data = json.loads(row)
|
||||
yield key, {
|
||||
"text": data["text"]
|
||||
}
|
||||
yield key, {"text": data["text"]}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"logiqa": {"description": "LogiQA is a dataset for testing human logical reasoning. It consists of 8,678 QA\ninstances, covering multiple types of deductive reasoning. Results show that state-\nof-the-art neural models perform by far worse than human ceiling. The dataset can\nalso serve as a benchmark for reinvestigating logical AI under the deep learning\nNLP setting.\n", "citation": "@misc{liu2020logiqa,\n title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning}, \n author={Jian Liu and Leyang Cui and Hanmeng Liu and Dandan Huang and Yile Wang and Yue Zhang},\n year={2020},\n eprint={2007.08124},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/lgw863/LogiQA-dataset", "license": "", "features": {"label": {"dtype": "string", "id": null, "_type": "Value"}, "context": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "logiqa", "config_name": "logiqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 6419852, "num_examples": 7376, "dataset_name": "logiqa"}, "test": {"name": "test", "num_bytes": 571705, "num_examples": 651, "dataset_name": "logiqa"}, "validation": {"name": "validation", "num_bytes": 562437, "num_examples": 651, "dataset_name": "logiqa"}}, "download_checksums": {"https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Train.txt": {"num_bytes": 6281272, "checksum": "7d5bb1f58278e33b395744cd2ad8d7600faa0b3c4d615c659a44ec1181d759fa"}, "https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Test.txt": {"num_bytes": 559060, "checksum": "359acb78c37802208f7fde9e2f6574b8526527c63d6a336f90a53f1932cb4701"}, "https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Eval.txt": {"num_bytes": 550021, "checksum": "4c49e6753b7262c001506b9151135abf722247035ab075dad93acdea5789c01f"}}, "download_size": 7390353, "post_processing_size": null, "dataset_size": 7553994, "size_in_bytes": 14944347}}
|
||||
{"logiqa": {"description": "LogiQA is a dataset for testing human logical reasoning. It consists of 8,678 QA\ninstances, covering multiple types of deductive reasoning. Results show that state-\nof-the-art neural models perform by far worse than human ceiling. The dataset can\nalso serve as a benchmark for reinvestigating logical AI under the deep learning\nNLP setting.\n", "citation": "@misc{liu2020logiqa,\n title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning}, \n author={Jian Liu and Leyang Cui and Hanmeng Liu and Dandan Huang and Yile Wang and Yue Zhang},\n year={2020},\n eprint={2007.08124},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/lgw863/LogiQA-dataset", "license": "", "features": {"label": {"dtype": "string", "id": null, "_type": "Value"}, "context": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "logiqa", "config_name": "logiqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 6419852, "num_examples": 7376, "dataset_name": "logiqa"}, "test": {"name": "test", "num_bytes": 571705, "num_examples": 651, "dataset_name": "logiqa"}, "validation": {"name": "validation", "num_bytes": 562437, "num_examples": 651, "dataset_name": "logiqa"}}, "download_checksums": {"https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Train.txt": {"num_bytes": 6281272, "checksum": "7d5bb1f58278e33b395744cd2ad8d7600faa0b3c4d615c659a44ec1181d759fa"}, "https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Test.txt": {"num_bytes": 559060, "checksum": "359acb78c37802208f7fde9e2f6574b8526527c63d6a336f90a53f1932cb4701"}, "https://raw.githubusercontent.com/lgw863/LogiQA-dataset/master/Eval.txt": {"num_bytes": 550021, "checksum": "4c49e6753b7262c001506b9151135abf722247035ab075dad93acdea5789c01f"}}, "download_size": 7390353, "post_processing_size": null, "dataset_size": 7553994, "size_in_bytes": 14944347}}
|
||||
|
||||
@@ -19,7 +19,7 @@ import datasets
|
||||
|
||||
_CITATION = """\
|
||||
@misc{liu2020logiqa,
|
||||
title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning},
|
||||
title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning},
|
||||
author={Jian Liu and Leyang Cui and Hanmeng Liu and Dandan Huang and Yile Wang and Yue Zhang},
|
||||
year={2020},
|
||||
eprint={2007.08124},
|
||||
@@ -54,7 +54,9 @@ class Logiqa(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="logiqa", version=VERSION, description="The LogiQA dataset."),
|
||||
datasets.BuilderConfig(
|
||||
name="logiqa", version=VERSION, description="The LogiQA dataset."
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -63,9 +65,7 @@ class Logiqa(datasets.GeneratorBasedBuilder):
|
||||
"label": datasets.Value("string"),
|
||||
"context": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"options": datasets.features.Sequence(
|
||||
datasets.Value("string")
|
||||
),
|
||||
"options": datasets.features.Sequence(datasets.Value("string")),
|
||||
}
|
||||
)
|
||||
return datasets.DatasetInfo(
|
||||
@@ -77,7 +77,11 @@ class Logiqa(datasets.GeneratorBasedBuilder):
|
||||
)
|
||||
|
||||
def _split_generators(self, dl_manager):
|
||||
urls = {"train": _URLS["train"], "test": _URLS["test"], "validation": _URLS["validation"]}
|
||||
urls = {
|
||||
"train": _URLS["train"],
|
||||
"test": _URLS["test"],
|
||||
"validation": _URLS["validation"],
|
||||
}
|
||||
data_dir = dl_manager.download_and_extract(urls)
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
@@ -91,10 +95,7 @@ class Logiqa(datasets.GeneratorBasedBuilder):
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": data_dir["test"],
|
||||
"split": "test"
|
||||
},
|
||||
gen_kwargs={"filepath": data_dir["test"], "split": "test"},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
@@ -110,6 +111,7 @@ class Logiqa(datasets.GeneratorBasedBuilder):
|
||||
def _generate_examples(self, filepath, split):
|
||||
def normalize(text):
|
||||
return text.replace(".", ". ").strip()
|
||||
|
||||
with open(filepath, encoding="utf-8") as f:
|
||||
data = f.read().strip().split("\n\n")
|
||||
for key, row in enumerate(data):
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"mutual": {"description": "MuTual is a retrieval-based dataset for multi-turn dialogue reasoning, which is\nmodified from Chinese high school English listening comprehension test data.\n\nThe MuTual dataset.", "citation": "@inproceedings{mutual,\n title = \"MuTual: A Dataset for Multi-Turn Dialogue Reasoning\",\n author = \"Cui, Leyang and Wu, Yu and Liu, Shujie and Zhang, Yue and Zhou, Ming\" ,\n booktitle = \"Proceedings of the 58th Conference of the Association for Computational Linguistics\",\n year = \"2020\",\n publisher = \"Association for Computational Linguistics\",\n}\n", "homepage": "https://github.com/Nealcly/MuTual", "license": "", "features": {"answers": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "article": {"dtype": "string", "id": null, "_type": "Value"}, "id": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "mutual", "config_name": "mutual", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 5141602, "num_examples": 7088, "dataset_name": "mutual"}, "test": {"name": "test", "num_bytes": 634396, "num_examples": 886, "dataset_name": "mutual"}, "validation": {"name": "validation", "num_bytes": 624271, "num_examples": 886, "dataset_name": "mutual"}}, "download_checksums": {"https://github.com/Nealcly/MuTual/archive/master.zip": {"num_bytes": 10997878, "checksum": "bb325cf6c672f0f02699993a37138b0fa0af6fcfc77ec81dfbe46add4d7b29f9"}}, "download_size": 10997878, "post_processing_size": null, "dataset_size": 6400269, "size_in_bytes": 17398147}, "mutual_plus": {"description": "MuTual is a retrieval-based dataset for multi-turn dialogue reasoning, which is\nmodified from Chinese high school English listening comprehension test data.\n\nMuTualPlus is a more difficult MuTual that replaces positive responses with a safe responses.", "citation": "@inproceedings{mutual,\n title = \"MuTual: A Dataset for Multi-Turn Dialogue Reasoning\",\n author = \"Cui, Leyang and Wu, Yu and Liu, Shujie and Zhang, Yue and Zhou, Ming\" ,\n booktitle = \"Proceedings of the 58th Conference of the Association for Computational Linguistics\",\n year = \"2020\",\n publisher = \"Association for Computational Linguistics\",\n}\n", "homepage": "https://github.com/Nealcly/MuTual", "license": "", "features": {"answers": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "article": {"dtype": "string", "id": null, "_type": "Value"}, "id": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "mutual", "config_name": "mutual_plus", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 4921179, "num_examples": 7088, "dataset_name": "mutual"}, "test": {"name": "test", "num_bytes": 606620, "num_examples": 886, "dataset_name": "mutual"}, "validation": {"name": "validation", "num_bytes": 597340, "num_examples": 886, "dataset_name": "mutual"}}, "download_checksums": {"https://github.com/Nealcly/MuTual/archive/master.zip": {"num_bytes": 10997878, "checksum": "bb325cf6c672f0f02699993a37138b0fa0af6fcfc77ec81dfbe46add4d7b29f9"}}, "download_size": 10997878, "post_processing_size": null, "dataset_size": 6125139, "size_in_bytes": 17123017}}
|
||||
{"mutual": {"description": "MuTual is a retrieval-based dataset for multi-turn dialogue reasoning, which is\nmodified from Chinese high school English listening comprehension test data.\n\nThe MuTual dataset.", "citation": "@inproceedings{mutual,\n title = \"MuTual: A Dataset for Multi-Turn Dialogue Reasoning\",\n author = \"Cui, Leyang and Wu, Yu and Liu, Shujie and Zhang, Yue and Zhou, Ming\" ,\n booktitle = \"Proceedings of the 58th Conference of the Association for Computational Linguistics\",\n year = \"2020\",\n publisher = \"Association for Computational Linguistics\",\n}\n", "homepage": "https://github.com/Nealcly/MuTual", "license": "", "features": {"answers": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "article": {"dtype": "string", "id": null, "_type": "Value"}, "id": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "mutual", "config_name": "mutual", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 5141602, "num_examples": 7088, "dataset_name": "mutual"}, "test": {"name": "test", "num_bytes": 634396, "num_examples": 886, "dataset_name": "mutual"}, "validation": {"name": "validation", "num_bytes": 624271, "num_examples": 886, "dataset_name": "mutual"}}, "download_checksums": {"https://github.com/Nealcly/MuTual/archive/master.zip": {"num_bytes": 10997878, "checksum": "bb325cf6c672f0f02699993a37138b0fa0af6fcfc77ec81dfbe46add4d7b29f9"}}, "download_size": 10997878, "post_processing_size": null, "dataset_size": 6400269, "size_in_bytes": 17398147}, "mutual_plus": {"description": "MuTual is a retrieval-based dataset for multi-turn dialogue reasoning, which is\nmodified from Chinese high school English listening comprehension test data.\n\nMuTualPlus is a more difficult MuTual that replaces positive responses with a safe responses.", "citation": "@inproceedings{mutual,\n title = \"MuTual: A Dataset for Multi-Turn Dialogue Reasoning\",\n author = \"Cui, Leyang and Wu, Yu and Liu, Shujie and Zhang, Yue and Zhou, Ming\" ,\n booktitle = \"Proceedings of the 58th Conference of the Association for Computational Linguistics\",\n year = \"2020\",\n publisher = \"Association for Computational Linguistics\",\n}\n", "homepage": "https://github.com/Nealcly/MuTual", "license": "", "features": {"answers": {"dtype": "string", "id": null, "_type": "Value"}, "options": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "article": {"dtype": "string", "id": null, "_type": "Value"}, "id": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "mutual", "config_name": "mutual_plus", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 4921179, "num_examples": 7088, "dataset_name": "mutual"}, "test": {"name": "test", "num_bytes": 606620, "num_examples": 886, "dataset_name": "mutual"}, "validation": {"name": "validation", "num_bytes": 597340, "num_examples": 886, "dataset_name": "mutual"}}, "download_checksums": {"https://github.com/Nealcly/MuTual/archive/master.zip": {"num_bytes": 10997878, "checksum": "bb325cf6c672f0f02699993a37138b0fa0af6fcfc77ec81dfbe46add4d7b29f9"}}, "download_size": 10997878, "post_processing_size": null, "dataset_size": 6125139, "size_in_bytes": 17123017}}
|
||||
|
||||
@@ -50,8 +50,14 @@ class Mutual(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="mutual", version=VERSION, description="The MuTual dataset."),
|
||||
datasets.BuilderConfig(name="mutual_plus", version=VERSION, description="MuTualPlus is a more difficult MuTual that replaces positive responses with a safe responses."),
|
||||
datasets.BuilderConfig(
|
||||
name="mutual", version=VERSION, description="The MuTual dataset."
|
||||
),
|
||||
datasets.BuilderConfig(
|
||||
name="mutual_plus",
|
||||
version=VERSION,
|
||||
description="MuTualPlus is a more difficult MuTual that replaces positive responses with a safe responses.",
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -79,7 +85,9 @@ class Mutual(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TRAIN,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"basepath": os.path.join(data_dir, "MuTual-master", "data", self.config.name, "train"),
|
||||
"basepath": os.path.join(
|
||||
data_dir, "MuTual-master", "data", self.config.name, "train"
|
||||
),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
@@ -87,7 +95,9 @@ class Mutual(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"basepath": os.path.join(data_dir, "MuTual-master", "data", self.config.name, "test"),
|
||||
"basepath": os.path.join(
|
||||
data_dir, "MuTual-master", "data", self.config.name, "test"
|
||||
),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
@@ -95,7 +105,9 @@ class Mutual(datasets.GeneratorBasedBuilder):
|
||||
name=datasets.Split.VALIDATION,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"basepath": os.path.join(data_dir, "MuTual-master", "data", self.config.name, "dev"),
|
||||
"basepath": os.path.join(
|
||||
data_dir, "MuTual-master", "data", self.config.name, "dev"
|
||||
),
|
||||
"split": "dev",
|
||||
},
|
||||
),
|
||||
@@ -109,7 +121,7 @@ class Mutual(datasets.GeneratorBasedBuilder):
|
||||
for file in sorted(Path(basepath).iterdir()):
|
||||
if file.suffix != ".txt":
|
||||
continue
|
||||
with open(file, "r", encoding='utf-8') as f:
|
||||
with open(file, "r", encoding="utf-8") as f:
|
||||
data_str = f.read()
|
||||
# Ignore the occasional empty file.
|
||||
if not data_str:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -103,10 +103,7 @@ class Pile(datasets.GeneratorBasedBuilder):
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": data_dir["test"],
|
||||
"split": "test"
|
||||
},
|
||||
gen_kwargs={"filepath": data_dir["test"], "split": "test"},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"quac": {"description": "Question Answering in Context (QuAC) is a dataset for modeling, understanding, and \nparticipating in information seeking dialog. Data instances consist of an interactive\ndialog between two crowd workers: (1) a student who poses a sequence of freeform\nquestions to learn as much as possible about a hidden Wikipedia text, and (2)\na teacher who answers the questions by providing short excerpts (spans) from the text.\n", "citation": "@article{choi2018quac,\n title={Quac: Question answering in context},\n author={Choi, Eunsol and He, He and Iyyer, Mohit and Yatskar, Mark and Yih, Wen-tau and Choi, Yejin and Liang, Percy and Zettlemoyer, Luke},\n journal={arXiv preprint arXiv:1808.07036},\n year={2018}\n}\n", "homepage": "https://quac.ai/", "license": "", "features": {"title": {"dtype": "string", "id": null, "_type": "Value"}, "section_title": {"dtype": "string", "id": null, "_type": "Value"}, "paragraph": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "quac", "config_name": "quac", "version": {"version_str": "1.1.0", "description": null, "major": 1, "minor": 1, "patch": 0}, "splits": {"train": {"name": "train", "num_bytes": 212391958, "num_examples": 83568, "dataset_name": "quac"}, "validation": {"name": "validation", "num_bytes": 20678483, "num_examples": 7354, "dataset_name": "quac"}}, "download_checksums": {"https://s3.amazonaws.com/my89public/quac/train_v0.2.json": {"num_bytes": 68114819, "checksum": "ff5cca5a2e4b4d1cb5b5ced68b9fce88394ef6d93117426d6d4baafbcc05c56a"}, "https://s3.amazonaws.com/my89public/quac/val_v0.2.json": {"num_bytes": 8929167, "checksum": "09e622916280ba04c9352acb1bc5bbe80f11a2598f6f34e934c51d9e6570f378"}}, "download_size": 77043986, "post_processing_size": null, "dataset_size": 233070441, "size_in_bytes": 310114427}}
|
||||
{"quac": {"description": "Question Answering in Context (QuAC) is a dataset for modeling, understanding, and \nparticipating in information seeking dialog. Data instances consist of an interactive\ndialog between two crowd workers: (1) a student who poses a sequence of freeform\nquestions to learn as much as possible about a hidden Wikipedia text, and (2)\na teacher who answers the questions by providing short excerpts (spans) from the text.\n", "citation": "@article{choi2018quac,\n title={Quac: Question answering in context},\n author={Choi, Eunsol and He, He and Iyyer, Mohit and Yatskar, Mark and Yih, Wen-tau and Choi, Yejin and Liang, Percy and Zettlemoyer, Luke},\n journal={arXiv preprint arXiv:1808.07036},\n year={2018}\n}\n", "homepage": "https://quac.ai/", "license": "", "features": {"title": {"dtype": "string", "id": null, "_type": "Value"}, "section_title": {"dtype": "string", "id": null, "_type": "Value"}, "paragraph": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "quac", "config_name": "quac", "version": {"version_str": "1.1.0", "description": null, "major": 1, "minor": 1, "patch": 0}, "splits": {"train": {"name": "train", "num_bytes": 212391958, "num_examples": 83568, "dataset_name": "quac"}, "validation": {"name": "validation", "num_bytes": 20678483, "num_examples": 7354, "dataset_name": "quac"}}, "download_checksums": {"https://s3.amazonaws.com/my89public/quac/train_v0.2.json": {"num_bytes": 68114819, "checksum": "ff5cca5a2e4b4d1cb5b5ced68b9fce88394ef6d93117426d6d4baafbcc05c56a"}, "https://s3.amazonaws.com/my89public/quac/val_v0.2.json": {"num_bytes": 8929167, "checksum": "09e622916280ba04c9352acb1bc5bbe80f11a2598f6f34e934c51d9e6570f378"}}, "download_size": 77043986, "post_processing_size": null, "dataset_size": 233070441, "size_in_bytes": 310114427}}
|
||||
|
||||
@@ -30,7 +30,7 @@ _CITATION = """\
|
||||
"""
|
||||
|
||||
_DESCRIPTION = """\
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
participating in information seeking dialog. Data instances consist of an interactive
|
||||
dialog between two crowd workers: (1) a student who poses a sequence of freeform
|
||||
questions to learn as much as possible about a hidden Wikipedia text, and (2)
|
||||
@@ -54,7 +54,9 @@ class Quac(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("1.1.0")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="quac", version=VERSION, description="The QuAC dataset"),
|
||||
datasets.BuilderConfig(
|
||||
name="quac", version=VERSION, description="The QuAC dataset"
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -90,10 +92,7 @@ class Quac(datasets.GeneratorBasedBuilder):
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
# These kwargs will be passed to _generate_examples
|
||||
gen_kwargs={
|
||||
"filepath": data_dir["validation"],
|
||||
"split": "validation"
|
||||
},
|
||||
gen_kwargs={"filepath": data_dir["validation"], "split": "validation"},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -105,7 +104,7 @@ class Quac(datasets.GeneratorBasedBuilder):
|
||||
for row in data:
|
||||
paragraph = row["paragraphs"][0]["context"].replace("CANNOTANSWER", "")
|
||||
qas = row["paragraphs"][0]["qas"]
|
||||
qa_pairs = [(qa['question'], qa['answers'][0]['text']) for qa in qas]
|
||||
qa_pairs = [(qa["question"], qa["answers"][0]["text"]) for qa in qas]
|
||||
for (question, answer) in qa_pairs:
|
||||
# Yields examples as (key, example) tuples
|
||||
yield key, {
|
||||
|
||||
@@ -44,13 +44,16 @@ _LICENSE = ""
|
||||
|
||||
|
||||
class SatAnalogies(datasets.GeneratorBasedBuilder):
|
||||
""" SAT (Scholastic Aptitude Test) Analogy Questions is a dataset comprising 374 multiple-choice analogy questions. """
|
||||
"""SAT (Scholastic Aptitude Test) Analogy Questions is a dataset comprising 374 multiple-choice analogy questions."""
|
||||
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name="sat_analogies", version=VERSION,
|
||||
description="The SAT Analogy Questions dataset"),
|
||||
datasets.BuilderConfig(
|
||||
name="sat_analogies",
|
||||
version=VERSION,
|
||||
description="The SAT Analogy Questions dataset",
|
||||
),
|
||||
]
|
||||
|
||||
@property
|
||||
@@ -68,9 +71,7 @@ class SatAnalogies(datasets.GeneratorBasedBuilder):
|
||||
{
|
||||
"source": datasets.Value("string"),
|
||||
"stem": datasets.Value("string"),
|
||||
"choices": datasets.features.Sequence(
|
||||
datasets.Value("string")
|
||||
),
|
||||
"choices": datasets.features.Sequence(datasets.Value("string")),
|
||||
"solution": datasets.Value("string"),
|
||||
}
|
||||
)
|
||||
@@ -108,7 +109,7 @@ class SatAnalogies(datasets.GeneratorBasedBuilder):
|
||||
if len(line) == 0 and record:
|
||||
data.append(record)
|
||||
record = []
|
||||
elif len(line) > 0 and line[0] == '#':
|
||||
elif len(line) > 0 and line[0] == "#":
|
||||
# Skip comments.
|
||||
continue
|
||||
else:
|
||||
@@ -120,8 +121,8 @@ class SatAnalogies(datasets.GeneratorBasedBuilder):
|
||||
choices = record[-6:-1]
|
||||
solution = record[-1]
|
||||
yield key, {
|
||||
'source': source,
|
||||
'stem': stem,
|
||||
'choices': choices,
|
||||
'solution': solution,
|
||||
"source": source,
|
||||
"stem": stem,
|
||||
"choices": choices,
|
||||
"solution": solution,
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"triviaqa": {"description": "TriviaQA is a reading comprehension dataset containing over 650K question-answer-evidence\ntriples. TriviaQA includes 95K question-answer pairs authored by trivia enthusiasts\nand independently gathered evidence documents, six per question on average, that provide\nhigh quality distant supervision for answering the questions.\n", "citation": "@InProceedings{JoshiTriviaQA2017,\n author = {Joshi, Mandar and Choi, Eunsol and Weld, Daniel S. and Zettlemoyer, Luke},\n title = {TriviaQA: A Large Scale Distantly Supervised Challenge Dataset for Reading Comprehension},\n booktitle = {Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics},\n month = {July},\n year = {2017},\n address = {Vancouver, Canada},\n publisher = {Association for Computational Linguistics},\n}\n", "homepage": "https://nlp.cs.washington.edu/triviaqa/", "license": "Apache License 2.0", "features": {"question_id": {"dtype": "string", "id": null, "_type": "Value"}, "question_source": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"aliases": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "value": {"dtype": "string", "id": null, "_type": "Value"}}, "search_results": {"feature": {"description": {"dtype": "string", "id": null, "_type": "Value"}, "filename": {"dtype": "string", "id": null, "_type": "Value"}, "rank": {"dtype": "int32", "id": null, "_type": "Value"}, "title": {"dtype": "string", "id": null, "_type": "Value"}, "url": {"dtype": "string", "id": null, "_type": "Value"}, "search_context": {"dtype": "string", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "triviaqa", "config_name": "triviaqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 1271393601, "num_examples": 87622, "dataset_name": "triviaqa"}, "validation": {"name": "validation", "num_bytes": 163819509, "num_examples": 11313, "dataset_name": "triviaqa"}}, "download_checksums": {"http://eaidata.bmk.sh/data/triviaqa-unfiltered.tar.gz": {"num_bytes": 546481381, "checksum": "adc19b42769062d241a8fbe834c56e58598d9322eb6c614e9f33a68a2cf5523e"}}, "download_size": 546481381, "post_processing_size": null, "dataset_size": 1435213110, "size_in_bytes": 1981694491}}
|
||||
{"triviaqa": {"description": "TriviaQA is a reading comprehension dataset containing over 650K question-answer-evidence\ntriples. TriviaQA includes 95K question-answer pairs authored by trivia enthusiasts\nand independently gathered evidence documents, six per question on average, that provide\nhigh quality distant supervision for answering the questions.\n", "citation": "@InProceedings{JoshiTriviaQA2017,\n author = {Joshi, Mandar and Choi, Eunsol and Weld, Daniel S. and Zettlemoyer, Luke},\n title = {TriviaQA: A Large Scale Distantly Supervised Challenge Dataset for Reading Comprehension},\n booktitle = {Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics},\n month = {July},\n year = {2017},\n address = {Vancouver, Canada},\n publisher = {Association for Computational Linguistics},\n}\n", "homepage": "https://nlp.cs.washington.edu/triviaqa/", "license": "Apache License 2.0", "features": {"question_id": {"dtype": "string", "id": null, "_type": "Value"}, "question_source": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "answer": {"aliases": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "value": {"dtype": "string", "id": null, "_type": "Value"}}, "search_results": {"feature": {"description": {"dtype": "string", "id": null, "_type": "Value"}, "filename": {"dtype": "string", "id": null, "_type": "Value"}, "rank": {"dtype": "int32", "id": null, "_type": "Value"}, "title": {"dtype": "string", "id": null, "_type": "Value"}, "url": {"dtype": "string", "id": null, "_type": "Value"}, "search_context": {"dtype": "string", "id": null, "_type": "Value"}}, "length": -1, "id": null, "_type": "Sequence"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "triviaqa", "config_name": "triviaqa", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"train": {"name": "train", "num_bytes": 1271393601, "num_examples": 87622, "dataset_name": "triviaqa"}, "validation": {"name": "validation", "num_bytes": 163819509, "num_examples": 11313, "dataset_name": "triviaqa"}}, "download_checksums": {"http://eaidata.bmk.sh/data/triviaqa-unfiltered.tar.gz": {"num_bytes": 546481381, "checksum": "adc19b42769062d241a8fbe834c56e58598d9322eb6c614e9f33a68a2cf5523e"}}, "download_size": 546481381, "post_processing_size": null, "dataset_size": 1435213110, "size_in_bytes": 1981694491}}
|
||||
|
||||
@@ -50,13 +50,14 @@ _URLS = "http://eaidata.bmk.sh/data/triviaqa-unfiltered.tar.gz"
|
||||
|
||||
|
||||
class Triviaqa(datasets.GeneratorBasedBuilder):
|
||||
""" TriviaQA is a reading comprehension dataset containing over 650K question-answer-evidence triples """
|
||||
"""TriviaQA is a reading comprehension dataset containing over 650K question-answer-evidence triples"""
|
||||
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(
|
||||
name="triviaqa", version=VERSION, description="The TriviaQA dataset"),
|
||||
name="triviaqa", version=VERSION, description="The TriviaQA dataset"
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -66,10 +67,10 @@ class Triviaqa(datasets.GeneratorBasedBuilder):
|
||||
"question_source": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"answer": {
|
||||
"aliases": datasets.features.Sequence(
|
||||
"aliases": datasets.features.Sequence(
|
||||
datasets.Value("string"),
|
||||
),
|
||||
"value": datasets.Value("string")
|
||||
"value": datasets.Value("string"),
|
||||
},
|
||||
"search_results": datasets.features.Sequence(
|
||||
{
|
||||
@@ -120,12 +121,24 @@ class Triviaqa(datasets.GeneratorBasedBuilder):
|
||||
for search_result in data["SearchResults"]:
|
||||
search_results.append(
|
||||
{
|
||||
"description": search_result["Description"] if "Description" in search_result else "",
|
||||
"filename": search_result["Filename"] if "Filename" in search_result else "",
|
||||
"rank": search_result["Rank"] if "Rank" in search_result else -1,
|
||||
"title": search_result["Title"] if "Title" in search_result else "",
|
||||
"url": search_result["Url"] if "Url" in search_result else "",
|
||||
"search_context": search_result["SearchContext"] if "SearchContext" in search_result else "",
|
||||
"description": search_result["Description"]
|
||||
if "Description" in search_result
|
||||
else "",
|
||||
"filename": search_result["Filename"]
|
||||
if "Filename" in search_result
|
||||
else "",
|
||||
"rank": search_result["Rank"]
|
||||
if "Rank" in search_result
|
||||
else -1,
|
||||
"title": search_result["Title"]
|
||||
if "Title" in search_result
|
||||
else "",
|
||||
"url": search_result["Url"]
|
||||
if "Url" in search_result
|
||||
else "",
|
||||
"search_context": search_result["SearchContext"]
|
||||
if "SearchContext" in search_result
|
||||
else "",
|
||||
}
|
||||
)
|
||||
yield key, {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"multiple_choice": {"description": "TruthfulQA is a benchmark to measure whether a language model is truthful in\ngenerating answers to questions. The benchmark comprises 817 questions that\nspan 38 categories, including health, law, finance and politics. Questions are\ncrafted so that some humans would answer falsely due to a false belief or\nmisconception. To perform well, models must avoid generating false answers\nlearned from imitating human texts.\n\nThe multiple choice TruthfulQA task", "citation": "@misc{lin2021truthfulqa,\n title={TruthfulQA: Measuring How Models Mimic Human Falsehoods},\n author={Stephanie Lin and Jacob Hilton and Owain Evans},\n year={2021},\n eprint={2109.07958},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/sylinrl/TruthfulQA", "license": "", "features": {"question": {"dtype": "string", "id": null, "_type": "Value"}, "mc1_targets": {"choices": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "labels": {"feature": {"dtype": "int32", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}, "mc2_targets": {"choices": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "labels": {"feature": {"dtype": "int32", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "truthfulqa", "config_name": "multiple_choice", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 610333, "num_examples": 817, "dataset_name": "truthfulqa"}}, "download_checksums": {"https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/data/mc_task.json": {"num_bytes": 710607, "checksum": "6eb4125d25750c0145c4be2dce00440736684ab6f74ce6bff2139571cc758954"}}, "download_size": 710607, "post_processing_size": null, "dataset_size": 610333, "size_in_bytes": 1320940}, "generation": {"description": "TruthfulQA is a benchmark to measure whether a language model is truthful in\ngenerating answers to questions. The benchmark comprises 817 questions that\nspan 38 categories, including health, law, finance and politics. Questions are\ncrafted so that some humans would answer falsely due to a false belief or\nmisconception. To perform well, models must avoid generating false answers\nlearned from imitating human texts.\n\nThe generative TruthfulQA task", "citation": "@misc{lin2021truthfulqa,\n title={TruthfulQA: Measuring How Models Mimic Human Falsehoods},\n author={Stephanie Lin and Jacob Hilton and Owain Evans},\n year={2021},\n eprint={2109.07958},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/sylinrl/TruthfulQA", "license": "", "features": {"category": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "best_answer": {"dtype": "string", "id": null, "_type": "Value"}, "correct_answers": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "incorrect_answers": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "source": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "truthfulqa", "config_name": "generation", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 463860, "num_examples": 817, "dataset_name": "truthfulqa"}}, "download_checksums": {"https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/TruthfulQA.csv": {"num_bytes": 443723, "checksum": "8d7dd15f033196140f032d97d30f037da7a7b1192c3f36f9937c1850925335a2"}}, "download_size": 443723, "post_processing_size": null, "dataset_size": 463860, "size_in_bytes": 907583}}
|
||||
{"multiple_choice": {"description": "TruthfulQA is a benchmark to measure whether a language model is truthful in\ngenerating answers to questions. The benchmark comprises 817 questions that\nspan 38 categories, including health, law, finance and politics. Questions are\ncrafted so that some humans would answer falsely due to a false belief or\nmisconception. To perform well, models must avoid generating false answers\nlearned from imitating human texts.\n\nThe multiple choice TruthfulQA task", "citation": "@misc{lin2021truthfulqa,\n title={TruthfulQA: Measuring How Models Mimic Human Falsehoods},\n author={Stephanie Lin and Jacob Hilton and Owain Evans},\n year={2021},\n eprint={2109.07958},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/sylinrl/TruthfulQA", "license": "", "features": {"question": {"dtype": "string", "id": null, "_type": "Value"}, "mc1_targets": {"choices": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "labels": {"feature": {"dtype": "int32", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}, "mc2_targets": {"choices": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "labels": {"feature": {"dtype": "int32", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "truthfulqa", "config_name": "multiple_choice", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 610333, "num_examples": 817, "dataset_name": "truthfulqa"}}, "download_checksums": {"https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/data/mc_task.json": {"num_bytes": 710607, "checksum": "6eb4125d25750c0145c4be2dce00440736684ab6f74ce6bff2139571cc758954"}}, "download_size": 710607, "post_processing_size": null, "dataset_size": 610333, "size_in_bytes": 1320940}, "generation": {"description": "TruthfulQA is a benchmark to measure whether a language model is truthful in\ngenerating answers to questions. The benchmark comprises 817 questions that\nspan 38 categories, including health, law, finance and politics. Questions are\ncrafted so that some humans would answer falsely due to a false belief or\nmisconception. To perform well, models must avoid generating false answers\nlearned from imitating human texts.\n\nThe generative TruthfulQA task", "citation": "@misc{lin2021truthfulqa,\n title={TruthfulQA: Measuring How Models Mimic Human Falsehoods},\n author={Stephanie Lin and Jacob Hilton and Owain Evans},\n year={2021},\n eprint={2109.07958},\n archivePrefix={arXiv},\n primaryClass={cs.CL}\n}\n", "homepage": "https://github.com/sylinrl/TruthfulQA", "license": "", "features": {"category": {"dtype": "string", "id": null, "_type": "Value"}, "question": {"dtype": "string", "id": null, "_type": "Value"}, "best_answer": {"dtype": "string", "id": null, "_type": "Value"}, "correct_answers": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "incorrect_answers": {"feature": {"dtype": "string", "id": null, "_type": "Value"}, "length": -1, "id": null, "_type": "Sequence"}, "source": {"dtype": "string", "id": null, "_type": "Value"}}, "post_processed": null, "supervised_keys": null, "task_templates": null, "builder_name": "truthfulqa", "config_name": "generation", "version": {"version_str": "0.0.1", "description": null, "major": 0, "minor": 0, "patch": 1}, "splits": {"validation": {"name": "validation", "num_bytes": 463860, "num_examples": 817, "dataset_name": "truthfulqa"}}, "download_checksums": {"https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/TruthfulQA.csv": {"num_bytes": 443723, "checksum": "8d7dd15f033196140f032d97d30f037da7a7b1192c3f36f9937c1850925335a2"}}, "download_size": 443723, "post_processing_size": null, "dataset_size": 463860, "size_in_bytes": 907583}}
|
||||
|
||||
@@ -65,38 +65,46 @@ class TruthfulqaConfig(datasets.BuilderConfig):
|
||||
|
||||
class Truthfulqa(datasets.GeneratorBasedBuilder):
|
||||
"""TruthfulQA is a benchmark to measure whether a language model is truthful in
|
||||
generating answers to questions."""
|
||||
generating answers to questions."""
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
TruthfulqaConfig(
|
||||
name="multiple_choice",
|
||||
url="https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/data/mc_task.json",
|
||||
features=datasets.Features({
|
||||
"question": datasets.Value("string"),
|
||||
"mc1_targets": {
|
||||
"choices": datasets.features.Sequence(datasets.Value("string")),
|
||||
"labels": datasets.features.Sequence(datasets.Value("int32")),
|
||||
},
|
||||
"mc2_targets": {
|
||||
"choices": datasets.features.Sequence(datasets.Value("string")),
|
||||
"labels": datasets.features.Sequence(datasets.Value("int32")),
|
||||
features=datasets.Features(
|
||||
{
|
||||
"question": datasets.Value("string"),
|
||||
"mc1_targets": {
|
||||
"choices": datasets.features.Sequence(datasets.Value("string")),
|
||||
"labels": datasets.features.Sequence(datasets.Value("int32")),
|
||||
},
|
||||
"mc2_targets": {
|
||||
"choices": datasets.features.Sequence(datasets.Value("string")),
|
||||
"labels": datasets.features.Sequence(datasets.Value("int32")),
|
||||
},
|
||||
}
|
||||
}),
|
||||
description="The multiple choice TruthfulQA task"
|
||||
),
|
||||
description="The multiple choice TruthfulQA task",
|
||||
),
|
||||
TruthfulqaConfig(
|
||||
name="generation",
|
||||
url="https://raw.githubusercontent.com/sylinrl/TruthfulQA/013686a06be7a7bde5bf8223943e106c7250123c/TruthfulQA.csv",
|
||||
features=datasets.Features({
|
||||
"category": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"best_answer": datasets.Value("string"),
|
||||
"correct_answers": datasets.features.Sequence(datasets.Value("string")),
|
||||
"incorrect_answers": datasets.features.Sequence(datasets.Value("string")),
|
||||
"source": datasets.Value("string"),
|
||||
}),
|
||||
description="The generative TruthfulQA task"
|
||||
)
|
||||
features=datasets.Features(
|
||||
{
|
||||
"category": datasets.Value("string"),
|
||||
"question": datasets.Value("string"),
|
||||
"best_answer": datasets.Value("string"),
|
||||
"correct_answers": datasets.features.Sequence(
|
||||
datasets.Value("string")
|
||||
),
|
||||
"incorrect_answers": datasets.features.Sequence(
|
||||
datasets.Value("string")
|
||||
),
|
||||
"source": datasets.Value("string"),
|
||||
}
|
||||
),
|
||||
description="The generative TruthfulQA task",
|
||||
),
|
||||
]
|
||||
|
||||
def _info(self):
|
||||
@@ -138,15 +146,15 @@ generating answers to questions."""
|
||||
"mc2_targets": {
|
||||
"choices": row["mc2_targets"].keys(),
|
||||
"labels": row["mc2_targets"].values(),
|
||||
}
|
||||
},
|
||||
}
|
||||
else:
|
||||
# Generation data is in a `CSV` file.
|
||||
with open(filepath, newline='') as f:
|
||||
with open(filepath, newline="") as f:
|
||||
contents = csv.DictReader(f)
|
||||
for key, row in enumerate(contents):
|
||||
# Ensure that references exist.
|
||||
if not row['Correct Answers'] or not row['Incorrect Answers']:
|
||||
if not row["Correct Answers"] or not row["Incorrect Answers"]:
|
||||
continue
|
||||
yield key, {
|
||||
"category": row["Category"],
|
||||
@@ -154,6 +162,8 @@ generating answers to questions."""
|
||||
"best_answer": row["Best Answer"],
|
||||
# split on ";"
|
||||
"correct_answers": row["Correct Answers"].strip().split(";"),
|
||||
"incorrect_answers": row["Incorrect Answers"].strip().split(";"),
|
||||
"incorrect_answers": row["Incorrect Answers"]
|
||||
.strip()
|
||||
.split(";"),
|
||||
"source": row["Source"],
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -64,8 +64,9 @@ class Unscramble(datasets.GeneratorBasedBuilder):
|
||||
VERSION = datasets.Version("0.0.1")
|
||||
|
||||
BUILDER_CONFIGS = [
|
||||
datasets.BuilderConfig(name=name, version=version,
|
||||
description=_DESCRIPTIONS[name])
|
||||
datasets.BuilderConfig(
|
||||
name=name, version=version, description=_DESCRIPTIONS[name]
|
||||
)
|
||||
for name, version in zip(_NAMES, [VERSION] * len(_NAMES))
|
||||
]
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -123,86 +123,111 @@ class Wikitext(datasets.GeneratorBasedBuilder):
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.test.tokens"), "split": "test"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.test.tokens"),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TRAIN,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.train.tokens"), "split": "train"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.train.tokens"),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.valid.tokens"), "split": "valid"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.valid.tokens"),
|
||||
"split": "valid",
|
||||
},
|
||||
),
|
||||
]
|
||||
else:
|
||||
if self.config.name == "wikitext-103-raw-v1":
|
||||
data_file = dl_manager.download_and_extract(
|
||||
self.config.data_url)
|
||||
data_file = dl_manager.download_and_extract(self.config.data_url)
|
||||
data_dir = os.path.join(data_file, "wikitext-103-raw")
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.test.raw"), "split": "test"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.test.raw"),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TRAIN,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.train.raw"), "split": "train"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.train.raw"),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.valid.raw"), "split": "valid"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.valid.raw"),
|
||||
"split": "valid",
|
||||
},
|
||||
),
|
||||
]
|
||||
else:
|
||||
if self.config.name == "wikitext-2-raw-v1":
|
||||
data_file = dl_manager.download_and_extract(
|
||||
self.config.data_url)
|
||||
data_file = dl_manager.download_and_extract(self.config.data_url)
|
||||
data_dir = os.path.join(data_file, "wikitext-2-raw")
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.test.raw"), "split": "test"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.test.raw"),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TRAIN,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.train.raw"), "split": "train"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.train.raw"),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.valid.raw"), "split": "valid"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.valid.raw"),
|
||||
"split": "valid",
|
||||
},
|
||||
),
|
||||
]
|
||||
else:
|
||||
if self.config.name == "wikitext-2-v1":
|
||||
data_file = dl_manager.download_and_extract(
|
||||
self.config.data_url)
|
||||
self.config.data_url
|
||||
)
|
||||
data_dir = os.path.join(data_file, "wikitext-2")
|
||||
return [
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TEST,
|
||||
gen_kwargs={"data_file": os.path.join(
|
||||
data_dir, "wiki.test.tokens"), "split": "test"},
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(
|
||||
data_dir, "wiki.test.tokens"
|
||||
),
|
||||
"split": "test",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.TRAIN,
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.train.tokens"),
|
||||
"data_file": os.path.join(
|
||||
data_dir, "wiki.train.tokens"
|
||||
),
|
||||
"split": "train",
|
||||
},
|
||||
),
|
||||
datasets.SplitGenerator(
|
||||
name=datasets.Split.VALIDATION,
|
||||
gen_kwargs={
|
||||
"data_file": os.path.join(data_dir, "wiki.valid.tokens"),
|
||||
"data_file": os.path.join(
|
||||
data_dir, "wiki.valid.tokens"
|
||||
),
|
||||
"split": "valid",
|
||||
},
|
||||
),
|
||||
@@ -216,12 +241,12 @@ class Wikitext(datasets.GeneratorBasedBuilder):
|
||||
data = f.read().split("\n")
|
||||
for line in data:
|
||||
rline = line.replace("= = =", "===").replace("= =", "==").strip()
|
||||
if rline.startswith('= ') and rline.strip().endswith(' ='):
|
||||
page = '\n'.join(ret)
|
||||
if rline.startswith("= ") and rline.strip().endswith(" ="):
|
||||
page = "\n".join(ret)
|
||||
if page.strip():
|
||||
yield key, {"page": page}
|
||||
key += 1
|
||||
ret = []
|
||||
ret.append(line)
|
||||
page = '\n'.join(ret)
|
||||
page = "\n".join(ret)
|
||||
yield key, {"page": page}
|
||||
|
||||
@@ -8,12 +8,14 @@ import mmap
|
||||
import tqdm
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def json_serial(obj):
|
||||
"""JSON serializer for objects not serializable by default json code"""
|
||||
|
||||
if isinstance(obj, (datetime.datetime,)):
|
||||
return obj.isoformat()
|
||||
raise TypeError ("Type %s not serializable" % type(obj))
|
||||
raise TypeError("Type %s not serializable" % type(obj))
|
||||
|
||||
|
||||
# Modified version of lm_dataformat Archive for single file.
|
||||
class Archive:
|
||||
@@ -21,26 +23,32 @@ class Archive:
|
||||
self.file_path = file_path
|
||||
dir_name = os.path.dirname(file_path)
|
||||
if dir_name:
|
||||
os.makedirs(dir_name, exist_ok=True)
|
||||
self.fh = open(self.file_path, 'wb')
|
||||
os.makedirs(dir_name, exist_ok=True)
|
||||
self.fh = open(self.file_path, "wb")
|
||||
self.cctx = zstandard.ZstdCompressor(level=compression_level)
|
||||
self.compressor = self.cctx.stream_writer(self.fh)
|
||||
|
||||
self.compressor = self.cctx.stream_writer(self.fh)
|
||||
|
||||
def add_data(self, data, meta={}):
|
||||
self.compressor.write(json.dumps({'text': data, 'meta': meta}, default=json_serial).encode('UTF-8') + b'\n')
|
||||
|
||||
self.compressor.write(
|
||||
json.dumps({"text": data, "meta": meta}, default=json_serial).encode(
|
||||
"UTF-8"
|
||||
)
|
||||
+ b"\n"
|
||||
)
|
||||
|
||||
def commit(self):
|
||||
self.compressor.flush(zstandard.FLUSH_FRAME)
|
||||
self.compressor.flush(zstandard.FLUSH_FRAME)
|
||||
self.fh.flush()
|
||||
self.fh.close()
|
||||
|
||||
|
||||
# Modified version of lm_dataformat Reader with self.fh set, allowing peeking for tqdm.
|
||||
class Reader:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def read(self, file, get_meta=False, autojoin_paragraphs=True, para_joiner='\n\n'):
|
||||
with open(file, 'rb') as fh:
|
||||
def read(self, file, get_meta=False, autojoin_paragraphs=True, para_joiner="\n\n"):
|
||||
with open(file, "rb") as fh:
|
||||
self.fh = fh
|
||||
cctx = zstandard.ZstdDecompressor()
|
||||
reader = io.BufferedReader(cctx.stream_reader(fh))
|
||||
@@ -52,53 +60,58 @@ class Reader:
|
||||
yield ob
|
||||
continue
|
||||
|
||||
text = ob['text']
|
||||
text = ob["text"]
|
||||
|
||||
if autojoin_paragraphs and isinstance(text, list):
|
||||
text = para_joiner.join(text)
|
||||
|
||||
if get_meta:
|
||||
yield text, (ob['meta'] if 'meta' in ob else {})
|
||||
yield text, (ob["meta"] if "meta" in ob else {})
|
||||
else:
|
||||
yield text
|
||||
|
||||
|
||||
class TextArchive:
|
||||
def __init__(self, file_path, mode="rb+"):
|
||||
self.file_path = file_path
|
||||
dir_name = os.path.dirname(file_path)
|
||||
if dir_name:
|
||||
os.makedirs(dir_name, exist_ok=True)
|
||||
os.makedirs(dir_name, exist_ok=True)
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
Path(file_path).touch()
|
||||
|
||||
self.fh = open(self.file_path, mode)
|
||||
|
||||
|
||||
self.fh = open(self.file_path, mode)
|
||||
|
||||
def add_data(self, data):
|
||||
self.fh.write(data.encode('UTF-8') + b'\n')
|
||||
|
||||
self.fh.write(data.encode("UTF-8") + b"\n")
|
||||
|
||||
def commit(self):
|
||||
self.fh.flush()
|
||||
self.fh.close()
|
||||
|
||||
|
||||
class TextReader:
|
||||
def __init__(self, file_path):
|
||||
self.file_path = file_path
|
||||
|
||||
# Optimized mmap read with infrequent tqdm updates to maintain speed
|
||||
# Tested up to 250MB/s.
|
||||
# Tested up to 250MB/s.
|
||||
def read_tqdm(self, update_frequency=10000):
|
||||
current_file_position = 0
|
||||
line_counter = 0
|
||||
with open(self.file_path, 'r') as fh, \
|
||||
tqdm.tqdm(total=os.path.getsize(self.file_path), dynamic_ncols=True,
|
||||
unit="byte", unit_scale=1) as progress:
|
||||
with open(self.file_path, "r") as fh, tqdm.tqdm(
|
||||
total=os.path.getsize(self.file_path),
|
||||
dynamic_ncols=True,
|
||||
unit="byte",
|
||||
unit_scale=1,
|
||||
) as progress:
|
||||
with mmap.mmap(fh.fileno(), length=0, access=mmap.ACCESS_READ) as mmap_obj:
|
||||
for line in iter(mmap_obj.readline, b""):
|
||||
line = line.decode("utf-8")
|
||||
line_counter += 1
|
||||
if line_counter == update_frequency:
|
||||
new_file_pos = mmap_obj.tell()
|
||||
new_file_pos = mmap_obj.tell()
|
||||
bytes_read = new_file_pos - current_file_position
|
||||
current_file_position = new_file_pos
|
||||
progress.update(bytes_read)
|
||||
@@ -107,24 +120,24 @@ class TextReader:
|
||||
|
||||
def read_and_tell(self):
|
||||
current_file_position = 0
|
||||
with open(self.file_path, 'r', encoding="utf8") as fh:
|
||||
with open(self.file_path, "r", encoding="utf8") as fh:
|
||||
with mmap.mmap(fh.fileno(), length=0, access=mmap.ACCESS_READ) as mmap_obj:
|
||||
for line in iter(mmap_obj.readline, b""):
|
||||
line = line.decode("utf-8")
|
||||
new_file_pos = mmap_obj.tell()
|
||||
line = line.decode("utf-8")
|
||||
new_file_pos = mmap_obj.tell()
|
||||
raw_bytes_read = new_file_pos - current_file_position
|
||||
current_file_position = new_file_pos
|
||||
yield line[:-1], raw_bytes_read
|
||||
|
||||
def read(self):
|
||||
with open(self.file_path, 'r', encoding="utf8") as fh:
|
||||
with open(self.file_path, "r", encoding="utf8") as fh:
|
||||
with mmap.mmap(fh.fileno(), length=0, access=mmap.ACCESS_READ) as mmap_obj:
|
||||
for line in iter(mmap_obj.readline, b""):
|
||||
line = line.decode("utf-8")
|
||||
line = line.decode("utf-8")
|
||||
yield line[:-1]
|
||||
|
||||
def read_slow(self):
|
||||
with open(self.file_path, 'r', encoding="utf8") as fh:
|
||||
with open(self.file_path, "r", encoding="utf8") as fh:
|
||||
while True:
|
||||
line = fh.readline()
|
||||
if line == -1 or line == "":
|
||||
@@ -132,16 +145,17 @@ class TextReader:
|
||||
else:
|
||||
yield line[:-1]
|
||||
|
||||
|
||||
# Optimized for speed. Decompresses the archive in shell before
|
||||
# using the mmap'd TextReader.
|
||||
class ZStdTextReader:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
self.file = file
|
||||
|
||||
def read_tqdm(self):
|
||||
def read_tqdm(self):
|
||||
decompressed_file = self.file[:-4]
|
||||
print("Decompressing file, please wait...")
|
||||
os.system(f"zstd -d {self.file}") # linux decompress is faster
|
||||
os.system(f"zstd -d {self.file}") # linux decompress is faster
|
||||
reader = TextReader(decompressed_file)
|
||||
yield from reader.read_tqdm()
|
||||
os.remove(decompressed_file)
|
||||
os.remove(decompressed_file)
|
||||
|
||||
@@ -49,7 +49,7 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
return f"data/{task_name}/{task_set}_{ngrams_n_size}grams_limit{limit}.overlaps"
|
||||
|
||||
lookups = {}
|
||||
duplicates = {} # (task_name, task_set): set(doc_ids)}
|
||||
duplicates = {} # (task_name, task_set): set(doc_ids)}
|
||||
sets_to_decontaminate = len(docs_by_task_set.keys())
|
||||
|
||||
for (task_name, task_set), docs in docs_by_task_set.items():
|
||||
@@ -57,19 +57,27 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
os.mkdir(f"data/{task_name}")
|
||||
|
||||
# Check if we've decontaminated this combination before
|
||||
overlaps_dump_path = get_overlaps_dump_path(task_name, task_set, ngrams_n_size, limit)
|
||||
overlaps_dump_path = get_overlaps_dump_path(
|
||||
task_name, task_set, ngrams_n_size, limit
|
||||
)
|
||||
if os.path.exists(overlaps_dump_path):
|
||||
duplicates[(task_name, task_set)] = pickle.load(open(overlaps_dump_path, "rb"))
|
||||
duplicates[(task_name, task_set)] = pickle.load(
|
||||
open(overlaps_dump_path, "rb")
|
||||
)
|
||||
sets_to_decontaminate -= 1
|
||||
continue
|
||||
else:
|
||||
duplicates[(task_name, task_set)] = set()
|
||||
|
||||
# Build/load the task lookup {ngram: set(documents)}.
|
||||
task_set_lookup_path = f"data/{task_name}/{task_set}_{ngrams_n_size}grams_limit{limit}.lookup"
|
||||
task_set_lookup_path = (
|
||||
f"data/{task_name}/{task_set}_{ngrams_n_size}grams_limit{limit}.lookup"
|
||||
)
|
||||
if os.path.exists(task_set_lookup_path):
|
||||
print(f"{task_set_lookup_path} available, loading...")
|
||||
lookups[(task_name, task_set)] = pickle.load(open(task_set_lookup_path, "rb"))
|
||||
print(f"{task_set_lookup_path} available, loading...")
|
||||
lookups[(task_name, task_set)] = pickle.load(
|
||||
open(task_set_lookup_path, "rb")
|
||||
)
|
||||
else:
|
||||
print(f"{task_set_lookup_path} not available, building...")
|
||||
lookup = collections.defaultdict(set)
|
||||
@@ -79,7 +87,7 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
for ngram in ngrams:
|
||||
lookup[ngram].add(doc_id)
|
||||
|
||||
pickle.dump(lookup, open(task_set_lookup_path,"wb"))
|
||||
pickle.dump(lookup, open(task_set_lookup_path, "wb"))
|
||||
lookups[(task_name, task_set)] = lookup
|
||||
|
||||
elapsed = time.perf_counter() - start
|
||||
@@ -89,7 +97,7 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
|
||||
if sets_to_decontaminate > 0:
|
||||
print("Merging lookups...")
|
||||
start = time.perf_counter()
|
||||
start = time.perf_counter()
|
||||
merged_lookup = collections.defaultdict(list)
|
||||
for (task_name, task_set), lookup in lookups.items():
|
||||
for ngram, doc_ids in lookup.items():
|
||||
@@ -112,20 +120,26 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
non_matching_unique = 0
|
||||
|
||||
current_ngram = ""
|
||||
for line in reader.read_tqdm(): # Scan training set ngrams file
|
||||
for line in reader.read_tqdm(): # Scan training set ngrams file
|
||||
total_ngrams += 1
|
||||
[ngram, document_id] = line.rsplit(" ", 1)
|
||||
if ngram != current_ngram: # Only need to match the ngram once in training set
|
||||
if (
|
||||
ngram != current_ngram
|
||||
): # Only need to match the ngram once in training set
|
||||
unique_ngrams += 1
|
||||
current_ngram = ngram
|
||||
if ngram in merged_lookup:
|
||||
matched_ngrams.append(ngram) # For logging
|
||||
matched_ngrams.append(ngram) # For logging
|
||||
matching_unique += 1
|
||||
for task_name, task_set, doc_ids in merged_lookup[ngram]:
|
||||
task_doc_set = duplicates[(task_name, task_set)]
|
||||
for doc_id in doc_ids: # Record contamination across all relevant task/set combos
|
||||
for (
|
||||
doc_id
|
||||
) in (
|
||||
doc_ids
|
||||
): # Record contamination across all relevant task/set combos
|
||||
task_doc_set.add(doc_id)
|
||||
del merged_lookup[ngram] # No point matching again
|
||||
del merged_lookup[ngram] # No point matching again
|
||||
else:
|
||||
non_matching_unique += 1
|
||||
|
||||
@@ -143,11 +157,12 @@ def get_train_overlap(docs_by_task_set, ngrams_path, limit):
|
||||
|
||||
print(duplicates)
|
||||
|
||||
# Dump overlaps separately
|
||||
# Dump overlaps separately
|
||||
for (task_name, task_set), doc_ids in duplicates.items():
|
||||
overlaps_dump_path = get_overlaps_dump_path(task_name, task_set, ngrams_n_size, limit)
|
||||
pickle.dump(doc_ids, open(overlaps_dump_path,"wb"))
|
||||
overlaps_dump_path = get_overlaps_dump_path(
|
||||
task_name, task_set, ngrams_n_size, limit
|
||||
)
|
||||
pickle.dump(doc_ids, open(overlaps_dump_path, "wb"))
|
||||
|
||||
# Strip task set and return
|
||||
return {task_name: doc_ids for (task_name, task_set), doc_ids in duplicates.items()}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from pprint import pprint
|
||||
# c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) janitor_util.cpp -o janitor_util$(python3-config --extension-suffix) -undefined dynamic_lookup
|
||||
try:
|
||||
import janitor_util
|
||||
|
||||
JANITOR_CPP = True
|
||||
except Exception as e:
|
||||
print("WARNING: C++ module could not be loaded. Janitor running in python mode")
|
||||
@@ -41,6 +42,7 @@ def word_ngrams(s, n):
|
||||
ngram_seqs = form_ngrams(iter(tokens), n)
|
||||
return (" ".join(ngram) for ngram in ngram_seqs)
|
||||
|
||||
|
||||
# Does character sequences only - combined faster function to play around with later
|
||||
# def word_ngrams_indices_combined(sequence, n):
|
||||
# current_word = ""
|
||||
@@ -70,7 +72,7 @@ def split_indices(s):
|
||||
"""Splits a string on whitespaces and records the indices of each in the original string.
|
||||
@:return generator((word, (start_idx, end_idx)), ...)
|
||||
"""
|
||||
return ((m.group(0), (m.start(), m.end() - 1)) for m in re.finditer(r'\S+', s))
|
||||
return ((m.group(0), (m.start(), m.end() - 1)) for m in re.finditer(r"\S+", s))
|
||||
|
||||
|
||||
def word_ngrams_indices(s, n):
|
||||
@@ -90,22 +92,27 @@ def word_ngrams_indices(s, n):
|
||||
# ([word, word, ...], [(start,end), (start,end), ...]),
|
||||
# ...
|
||||
# )
|
||||
ngram_indices_pairs = (zip(*ngram_with_indices) for ngram_with_indices in ngram_seqs_with_indices)
|
||||
ngram_indices_pairs = (
|
||||
zip(*ngram_with_indices) for ngram_with_indices in ngram_seqs_with_indices
|
||||
)
|
||||
|
||||
# Generator of ( (word_ngram, (start, end)), (word_ngram, start, end)), ...)
|
||||
return ((" ".join(ngram_seq), (indices[0][0], indices[-1][1])) for ngram_seq, indices in ngram_indices_pairs)
|
||||
return (
|
||||
(" ".join(ngram_seq), (indices[0][0], indices[-1][1]))
|
||||
for ngram_seq, indices in ngram_indices_pairs
|
||||
)
|
||||
|
||||
|
||||
class Janitor:
|
||||
|
||||
# FIXME delete_chars: Should anything else go here? Special chars?
|
||||
def __init__(
|
||||
self,
|
||||
ngram_n=13,
|
||||
window_to_remove=200,
|
||||
too_dirty_cutoff=10,
|
||||
minimum_slice_length=200,
|
||||
delete_chars=string.punctuation
|
||||
self,
|
||||
ngram_n=13,
|
||||
window_to_remove=200,
|
||||
too_dirty_cutoff=10,
|
||||
minimum_slice_length=200,
|
||||
delete_chars=string.punctuation,
|
||||
):
|
||||
self.ngram_n = ngram_n
|
||||
self.window_to_remove = window_to_remove
|
||||
@@ -121,7 +128,7 @@ class Janitor:
|
||||
self.translation_table = str.maketrans(
|
||||
string.ascii_lowercase + string.ascii_uppercase, # These characters
|
||||
string.ascii_lowercase * 2, # Become these characters
|
||||
self.delete_chars # These are deleted
|
||||
self.delete_chars, # These are deleted
|
||||
)
|
||||
|
||||
##############
|
||||
@@ -129,14 +136,13 @@ class Janitor:
|
||||
##############
|
||||
|
||||
def save_contamination_ngrams(self, filename):
|
||||
with open(filename, 'wb') as fp:
|
||||
with open(filename, "wb") as fp:
|
||||
pickle.dump(filename, fp)
|
||||
|
||||
def load_contamination_ngrams(self, filename):
|
||||
with open(filename, 'rb') as fp:
|
||||
with open(filename, "rb") as fp:
|
||||
self.dirt_ngrams = pickle.load(fp)
|
||||
|
||||
|
||||
##############
|
||||
# Call these :)
|
||||
##############
|
||||
@@ -171,11 +177,11 @@ class Janitor:
|
||||
end = min(len(dirty_string), end + self.window_to_remove)
|
||||
|
||||
if start - splice_idx > self.minimum_slice_length:
|
||||
clean_chunks.append(dirty_string[splice_idx: start])
|
||||
clean_chunks.append(dirty_string[splice_idx:start])
|
||||
splice_idx = end
|
||||
|
||||
if end < len(dirty_string) - self.minimum_slice_length:
|
||||
clean_chunks.append(dirty_string[end+1:])
|
||||
clean_chunks.append(dirty_string[end + 1 :])
|
||||
|
||||
return clean_chunks
|
||||
|
||||
@@ -184,10 +190,14 @@ class Janitor:
|
||||
##############
|
||||
|
||||
def register_contaminant_cpp(self, dirt_string):
|
||||
self.dirt_ngrams.update(janitor_util.clean_ngram(dirt_string, self.delete_chars, self.ngram_n))
|
||||
self.dirt_ngrams.update(
|
||||
janitor_util.clean_ngram(dirt_string, self.delete_chars, self.ngram_n)
|
||||
)
|
||||
|
||||
def clean_cpp(self, dirty_string):
|
||||
contamination_indices = janitor_util.clean_ngram_with_indices(dirty_string, self.delete_chars, self.ngram_n)
|
||||
contamination_indices = janitor_util.clean_ngram_with_indices(
|
||||
dirty_string, self.delete_chars, self.ngram_n
|
||||
)
|
||||
return self._split_chunks(dirty_string, contamination_indices)
|
||||
|
||||
##############
|
||||
@@ -198,7 +208,9 @@ class Janitor:
|
||||
return s.translate(self.translation_table)
|
||||
|
||||
def register_contaminant_python(self, dirt_string):
|
||||
self.dirt_ngrams.update(word_ngrams(self.normalize_string(dirt_string), self.ngram_n))
|
||||
self.dirt_ngrams.update(
|
||||
word_ngrams(self.normalize_string(dirt_string), self.ngram_n)
|
||||
)
|
||||
|
||||
def clean_python(self, dirty_string):
|
||||
contamination_indices = (
|
||||
@@ -249,29 +261,29 @@ class Janitor:
|
||||
# data = f.read()
|
||||
# jan = Janitor(too_dirty_cutoff=1000)
|
||||
# jan.register_contaminant('''
|
||||
# theories is that there is a connection between "geekdom" and autism.
|
||||
# theories is that there is a connection between "geekdom" and autism.
|
||||
# This is hinted, for instance, by a ''Wired Magazine'' article in 2001 entitled "
|
||||
# The [[Geek]] Syndrome", which is a point argued by many in the autism rights
|
||||
# movement{{ref|Wired}}. This article, many professionals assert, is just one example of
|
||||
# The [[Geek]] Syndrome", which is a point argued by many in the autism rights
|
||||
# movement{{ref|Wired}}. This article, many professionals assert, is just one example of
|
||||
# the media's application of mental disease labels to what is actually variant normal behavior
|
||||
# &mdash;they argue that shyness, lack of athletic ability or social skills, and intellectual
|
||||
# interests, even when they seem unusual to others, are not in themselves signs of autism or
|
||||
# interests, even when they seem unusual to others, are not in themselves signs of autism or
|
||||
# Asperger's syndrome. Others assert that it is actually the medical profession which is applying
|
||||
# mental disease labels to children who in the past would have simply been accepted as a little
|
||||
# different or even labeled 'gifted'. See [[clinomorphism]] for further discussion of this issue.
|
||||
# Due to the recent publicity surrounding autism and autis
|
||||
# ultan Al Nahyan]] granted [[Petroleum]] concessions, and oil was first found in 1958. At first,
|
||||
# oil money had a marginal impact. A few lowrise concete buildings were erected, and the first
|
||||
# paved road was completed in 1961, but Sheikh Shakbut, uncertain whether the new oil royalties
|
||||
# would last, took a cautious approach, prefering to save the revenue rather than investing it in
|
||||
# development. His brother, [[Zayed bin Sultan Al Nahayan]], saw that oil wealth had the potential
|
||||
# to transform Abu Dhabi. The ruling Al Nahayan family decided that Sheikh Zayed should replace his
|
||||
# brother as Ruler and carry out his vision of developing the country. On [[August 6]], [[1966]],
|
||||
# with the assistance of the British, Sheikh Zayed became the new ruler. See generally, Al-Fahim, M,
|
||||
# ''From Rags to Riches: A Story of Abu Dhabi'', Chapter Six (London Centre of Arab Studies, 1995),
|
||||
# ISBN 1 900404 00 1. With the announcement by Britain in 1968 that it would withdraw from the
|
||||
# Gulf area by 1971, Sheikh Zayed became the main driving force behind the formation of the
|
||||
# [[United Arab Emirates]]. After the Emirates gained independence in 1971,
|
||||
# oil money had a marginal impact. A few lowrise concete buildings were erected, and the first
|
||||
# paved road was completed in 1961, but Sheikh Shakbut, uncertain whether the new oil royalties
|
||||
# would last, took a cautious approach, prefering to save the revenue rather than investing it in
|
||||
# development. His brother, [[Zayed bin Sultan Al Nahayan]], saw that oil wealth had the potential
|
||||
# to transform Abu Dhabi. The ruling Al Nahayan family decided that Sheikh Zayed should replace his
|
||||
# brother as Ruler and carry out his vision of developing the country. On [[August 6]], [[1966]],
|
||||
# with the assistance of the British, Sheikh Zayed became the new ruler. See generally, Al-Fahim, M,
|
||||
# ''From Rags to Riches: A Story of Abu Dhabi'', Chapter Six (London Centre of Arab Studies, 1995),
|
||||
# ISBN 1 900404 00 1. With the announcement by Britain in 1968 that it would withdraw from the
|
||||
# Gulf area by 1971, Sheikh Zayed became the main driving force behind the formation of the
|
||||
# [[United Arab Emirates]]. After the Emirates gained independence in 1971,
|
||||
# ''')
|
||||
# """
|
||||
|
||||
|
||||
+80
-44
@@ -11,19 +11,29 @@ import numpy as np
|
||||
from lm_eval.utils import positional_deprecated, run_task_tests
|
||||
from lm_eval.decontamination.decontaminate import get_train_overlap
|
||||
|
||||
|
||||
@positional_deprecated
|
||||
def simple_evaluate(model, model_args=None, tasks=[],
|
||||
num_fewshot=0, batch_size=None, device=None,
|
||||
no_cache=False, limit=None, bootstrap_iters=100000,
|
||||
description_dict=None, check_integrity=False,
|
||||
decontamination_ngrams_path=None):
|
||||
def simple_evaluate(
|
||||
model,
|
||||
model_args=None,
|
||||
tasks=[],
|
||||
num_fewshot=0,
|
||||
batch_size=None,
|
||||
device=None,
|
||||
no_cache=False,
|
||||
limit=None,
|
||||
bootstrap_iters=100000,
|
||||
description_dict=None,
|
||||
check_integrity=False,
|
||||
decontamination_ngrams_path=None,
|
||||
):
|
||||
|
||||
"""Instantiate and evaluate a model on a list of tasks.
|
||||
|
||||
:param model: Union[str, LM]
|
||||
Name of model or LM object, see lm_eval.models.get_model
|
||||
:param model_args: Optional[str]
|
||||
String arguments for each model class, see LM.create_from_arg_string.
|
||||
String arguments for each model class, see LM.create_from_arg_string.
|
||||
Ignored if `model` argument is a LM object.
|
||||
:param tasks: list[Union[str, Task]]
|
||||
List of task names or Task objects. Task objects will be taken to have name task.EVAL_HARNESS_NAME if defined and type(task).__name__ otherwise.
|
||||
@@ -40,7 +50,7 @@ def simple_evaluate(model, model_args=None, tasks=[],
|
||||
:param bootstrap_iters:
|
||||
Number of iterations for bootstrap statistics
|
||||
:param description_dict: dict[str, str]
|
||||
Dictionary of custom task descriptions of the form: `task_name: description`
|
||||
Dictionary of custom task descriptions of the form: `task_name: description`
|
||||
:param check_integrity: bool
|
||||
Whether to run the relevant part of the test suite for the tasks
|
||||
:return
|
||||
@@ -52,19 +62,25 @@ def simple_evaluate(model, model_args=None, tasks=[],
|
||||
assert tasks != [], "No tasks specified"
|
||||
|
||||
if isinstance(model, str):
|
||||
if model_args is None: model_args = ""
|
||||
lm = lm_eval.models.get_model(model).create_from_arg_string(model_args, {
|
||||
'batch_size': batch_size, 'device': device
|
||||
})
|
||||
if model_args is None:
|
||||
model_args = ""
|
||||
lm = lm_eval.models.get_model(model).create_from_arg_string(
|
||||
model_args, {"batch_size": batch_size, "device": device}
|
||||
)
|
||||
else:
|
||||
assert isinstance(model, lm_eval.base.LM)
|
||||
lm = model
|
||||
|
||||
if not no_cache:
|
||||
lm = lm_eval.base.CachingLM(
|
||||
lm, 'lm_cache/' + model + '_' + model_args.replace('=', '-').replace(',', '_').replace('/', '-') + '.db'
|
||||
lm,
|
||||
"lm_cache/"
|
||||
+ model
|
||||
+ "_"
|
||||
+ model_args.replace("=", "-").replace(",", "_").replace("/", "-")
|
||||
+ ".db",
|
||||
)
|
||||
|
||||
|
||||
task_dict = lm_eval.tasks.get_task_dict(tasks)
|
||||
|
||||
if check_integrity:
|
||||
@@ -76,7 +92,7 @@ def simple_evaluate(model, model_args=None, tasks=[],
|
||||
num_fewshot=num_fewshot,
|
||||
limit=limit,
|
||||
description_dict=description_dict,
|
||||
decontamination_ngrams_path=decontamination_ngrams_path,
|
||||
decontamination_ngrams_path=decontamination_ngrams_path,
|
||||
)
|
||||
|
||||
# add info about the model and few shot config
|
||||
@@ -89,16 +105,26 @@ def simple_evaluate(model, model_args=None, tasks=[],
|
||||
"no_cache": no_cache,
|
||||
"limit": limit,
|
||||
"bootstrap_iters": bootstrap_iters,
|
||||
"description_dict": description_dict
|
||||
"description_dict": description_dict,
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
|
||||
decontaminate_suffix = "_decontaminate"
|
||||
|
||||
|
||||
@positional_deprecated
|
||||
def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None, bootstrap_iters=100000, description_dict=None,
|
||||
decontamination_ngrams_path=None):
|
||||
def evaluate(
|
||||
lm,
|
||||
task_dict,
|
||||
provide_description=None,
|
||||
num_fewshot=0,
|
||||
limit=None,
|
||||
bootstrap_iters=100000,
|
||||
description_dict=None,
|
||||
decontamination_ngrams_path=None,
|
||||
):
|
||||
"""Instantiate and evaluate a model on a list of tasks.
|
||||
|
||||
:param lm: obj
|
||||
@@ -114,7 +140,7 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
:param bootstrap_iters:
|
||||
Number of iterations for bootstrap statistics
|
||||
:param description_dict: dict[str, str]
|
||||
Dictionary of custom task descriptions of the form: `task_name: description`
|
||||
Dictionary of custom task descriptions of the form: `task_name: description`
|
||||
:return
|
||||
Dictionary of results
|
||||
"""
|
||||
@@ -124,14 +150,16 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
assert not provide_description # not implemented.
|
||||
if provide_description is not None:
|
||||
# nudge people to not specify it at all
|
||||
print("WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict")
|
||||
print(
|
||||
"WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict"
|
||||
)
|
||||
|
||||
decontaminate = decontamination_ngrams_path is not None
|
||||
|
||||
task_dict_items = [
|
||||
(name, task)
|
||||
for name, task in task_dict.items()
|
||||
if(task.has_validation_docs() or task.has_test_docs())
|
||||
if (task.has_validation_docs() or task.has_test_docs())
|
||||
]
|
||||
|
||||
results = collections.defaultdict(dict)
|
||||
@@ -140,7 +168,7 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
requests = collections.defaultdict(list)
|
||||
requests_origin = collections.defaultdict(list)
|
||||
|
||||
overlaps = collections.defaultdict(list) # {task_name: contaminated_docs}
|
||||
overlaps = collections.defaultdict(list) # {task_name: contaminated_docs}
|
||||
|
||||
# If we ever run into issues where the eval tasks don't fit in memory and we can't afford a machine with bigger
|
||||
# memory, we can always modify this plumbing to support that, but I didn't want to include it just yet because
|
||||
@@ -159,9 +187,9 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
# TODO: the test-fallback-to-val system isn't final, we should revisit it at some point
|
||||
if task.has_test_docs():
|
||||
task_doc_func = task.test_docs
|
||||
task_set = "test" # Required for caching in the decontamination
|
||||
task_set = "test" # Required for caching in the decontamination
|
||||
elif task.has_validation_docs():
|
||||
task_set = "val" # Required for caching in the decontamination
|
||||
task_set = "val" # Required for caching in the decontamination
|
||||
task_doc_func = task.validation_docs
|
||||
else:
|
||||
raise RuntimeError("Task has neither test_docs nor validation_docs")
|
||||
@@ -172,19 +200,22 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
rnd.seed(42)
|
||||
rnd.shuffle(task_docs)
|
||||
|
||||
description = description_dict[task_name] if description_dict and task_name in description_dict else ""
|
||||
description = (
|
||||
description_dict[task_name]
|
||||
if description_dict and task_name in description_dict
|
||||
else ""
|
||||
)
|
||||
|
||||
for doc_id, doc in enumerate(itertools.islice(task_docs, 0, limit)):
|
||||
|
||||
if decontaminate and task.should_decontaminate():
|
||||
docs_for_decontamination[(task_name, task_set)].append(task.doc_to_decontamination_query(doc))
|
||||
docs_for_decontamination[(task_name, task_set)].append(
|
||||
task.doc_to_decontamination_query(doc)
|
||||
)
|
||||
|
||||
docs[(task_name, doc_id)] = doc
|
||||
ctx = task.fewshot_context(
|
||||
doc=doc,
|
||||
num_fewshot=num_fewshot,
|
||||
rnd=rnd,
|
||||
description=description
|
||||
doc=doc, num_fewshot=num_fewshot, rnd=rnd, description=description
|
||||
)
|
||||
reqs = task.construct_requests(doc, ctx)
|
||||
if not isinstance(reqs, (list, tuple)):
|
||||
@@ -198,7 +229,9 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
# Compare all tasks/sets at once to ensure a single training set scan
|
||||
if decontaminate:
|
||||
print("Finding train/test overlap, please wait...")
|
||||
overlaps = get_train_overlap(docs_for_decontamination, decontamination_ngrams_path, limit)
|
||||
overlaps = get_train_overlap(
|
||||
docs_for_decontamination, decontamination_ngrams_path, limit
|
||||
)
|
||||
|
||||
# all responses for each (task, doc)
|
||||
process_res_queue = collections.defaultdict(list)
|
||||
@@ -212,11 +245,13 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
|
||||
print("Running", reqtype, "requests")
|
||||
resps = getattr(lm, reqtype)([req.args for req in reqs])
|
||||
resps = [x if req.index is None else x[req.index] for x, req in zip(resps, reqs)]
|
||||
resps = [
|
||||
x if req.index is None else x[req.index] for x, req in zip(resps, reqs)
|
||||
]
|
||||
|
||||
for resp, (i, task_name, doc, doc_id) in zip(resps, requests_origin[reqtype]):
|
||||
process_res_queue[(task_name, doc_id)].append((i, resp))
|
||||
|
||||
|
||||
vals = collections.defaultdict(list)
|
||||
|
||||
# unpack results and sort back in order and return control to Task
|
||||
@@ -235,13 +270,15 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
if decontaminate and task_name in overlaps:
|
||||
if doc_id not in overlaps[task_name]:
|
||||
vals[(task_name, metric + decontaminate_suffix)].append(value)
|
||||
|
||||
|
||||
# aggregate results
|
||||
for (task_name, metric), items in vals.items():
|
||||
task = task_dict[task_name]
|
||||
real_metric = metric # key when looking up the metric with task.aggregation
|
||||
real_metric = metric # key when looking up the metric with task.aggregation
|
||||
if metric.endswith(decontaminate_suffix):
|
||||
real_metric = metric.replace(decontaminate_suffix, "") # decontaminated still uses the same metric
|
||||
real_metric = metric.replace(
|
||||
decontaminate_suffix, ""
|
||||
) # decontaminated still uses the same metric
|
||||
results[task_name][metric] = task.aggregation()[real_metric](items)
|
||||
|
||||
# hotfix: bleu, chrf, ter seem to be really expensive to bootstrap
|
||||
@@ -249,16 +286,15 @@ def evaluate(lm, task_dict, provide_description=None, num_fewshot=0, limit=None,
|
||||
|
||||
stderr = lm_eval.metrics.stderr_for_metric(
|
||||
metric=task.aggregation()[real_metric],
|
||||
bootstrap_iters=min(bootstrap_iters, 1000) if metric in ["bleu", "chrf", "ter"] else bootstrap_iters,
|
||||
bootstrap_iters=min(bootstrap_iters, 1000)
|
||||
if metric in ["bleu", "chrf", "ter"]
|
||||
else bootstrap_iters,
|
||||
)
|
||||
|
||||
|
||||
if stderr is not None:
|
||||
results[task_name][metric + "_stderr"] = stderr(items)
|
||||
|
||||
return {
|
||||
"results": dict(results),
|
||||
"versions": dict(versions)
|
||||
}
|
||||
|
||||
return {"results": dict(results), "versions": dict(versions)}
|
||||
|
||||
|
||||
def make_table(result_dict):
|
||||
@@ -280,9 +316,9 @@ def make_table(result_dict):
|
||||
|
||||
if m + "_stderr" in dic:
|
||||
se = dic[m + "_stderr"]
|
||||
values.append([k, version, m, '%.4f' % v, '±', '%.4f' % se])
|
||||
values.append([k, version, m, "%.4f" % v, "±", "%.4f" % se])
|
||||
else:
|
||||
values.append([k, version, m, '%.4f' % v, '', ''])
|
||||
values.append([k, version, m, "%.4f" % v, "", ""])
|
||||
k = ""
|
||||
version = ""
|
||||
md_writer.value_matrix = values
|
||||
|
||||
+15
-10
@@ -103,6 +103,7 @@ def weighted_mean(items):
|
||||
def weighted_perplexity(items):
|
||||
return math.exp(-weighted_mean(items))
|
||||
|
||||
|
||||
def bits_per_byte(items):
|
||||
return -weighted_mean(items) / math.log(2)
|
||||
|
||||
@@ -184,8 +185,10 @@ def _sacreformat(refs, preds):
|
||||
|
||||
return refs, preds
|
||||
|
||||
|
||||
# stderr stuff
|
||||
|
||||
|
||||
class _bootstrap_internal:
|
||||
def __init__(self, f, n):
|
||||
self.f = f
|
||||
@@ -203,9 +206,10 @@ class _bootstrap_internal:
|
||||
|
||||
def bootstrap_stderr(f, xs, iters):
|
||||
import multiprocessing as mp
|
||||
|
||||
pool = mp.Pool(mp.cpu_count())
|
||||
# this gives a biased estimate of the stderr (i.e w/ the mean, it gives something
|
||||
# equivalent to stderr calculated without Bessel's correction in the stddev.
|
||||
# equivalent to stderr calculated without Bessel's correction in the stddev.
|
||||
# Unfortunately, I haven't been able to figure out what the right correction is
|
||||
# to make the bootstrap unbiased - i considered multiplying by sqrt(n/(n-1)) but
|
||||
# that would be ad-hoc and I can't prove that that would actually be an unbiased estimator)
|
||||
@@ -213,10 +217,15 @@ def bootstrap_stderr(f, xs, iters):
|
||||
res = []
|
||||
chunk_size = min(1000, iters)
|
||||
from tqdm import tqdm
|
||||
|
||||
print("bootstrapping for stddev:", f.__name__)
|
||||
for bootstrap in tqdm(pool.imap(
|
||||
for bootstrap in tqdm(
|
||||
pool.imap(
|
||||
_bootstrap_internal(f, chunk_size),
|
||||
[(i, xs) for i in range(iters // chunk_size)]), total=iters // chunk_size):
|
||||
[(i, xs) for i in range(iters // chunk_size)],
|
||||
),
|
||||
total=iters // chunk_size,
|
||||
):
|
||||
# sample w replacement
|
||||
res.extend(bootstrap)
|
||||
|
||||
@@ -238,17 +247,13 @@ def stderr_for_metric(metric, bootstrap_iters):
|
||||
if metric in bootstrappable:
|
||||
return lambda x: bootstrap_stderr(metric, x, iters=bootstrap_iters)
|
||||
|
||||
stderr = {
|
||||
mean: mean_stderr,
|
||||
acc_all: acc_all_stderr
|
||||
|
||||
}
|
||||
stderr = {mean: mean_stderr, acc_all: acc_all_stderr}
|
||||
|
||||
return stderr.get(metric, None)
|
||||
|
||||
|
||||
def yesno(x):
|
||||
if x:
|
||||
return 'yes'
|
||||
return "yes"
|
||||
else:
|
||||
return 'no'
|
||||
return "no"
|
||||
|
||||
+42
-19
@@ -4,15 +4,22 @@ from lm_eval.base import BaseLM
|
||||
|
||||
|
||||
class HFLM(BaseLM):
|
||||
|
||||
def __init__(self, device='cuda', pretrained='gpt2', revision='main', subfolder=None, tokenizer=None, batch_size=1):
|
||||
def __init__(
|
||||
self,
|
||||
device="cuda",
|
||||
pretrained="gpt2",
|
||||
revision="main",
|
||||
subfolder=None,
|
||||
tokenizer=None,
|
||||
batch_size=1,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
assert isinstance(device, str)
|
||||
assert isinstance(pretrained, str)
|
||||
assert isinstance(batch_size, int)
|
||||
|
||||
if device:
|
||||
if device:
|
||||
if device not in ["cuda", "cpu"]:
|
||||
device = int(device)
|
||||
self._device = torch.device(device)
|
||||
@@ -20,28 +27,47 @@ class HFLM(BaseLM):
|
||||
else:
|
||||
print("Device not specificed")
|
||||
print(f"Cuda Available? {torch.cuda.is_available()}")
|
||||
self._device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
|
||||
self._device = (
|
||||
torch.device("cuda")
|
||||
if torch.cuda.is_available()
|
||||
else torch.device("cpu")
|
||||
)
|
||||
|
||||
# TODO: update this to be less of a hack once subfolder is fixed in HF
|
||||
self.gpt2 = transformers.AutoModelForCausalLM.from_pretrained(
|
||||
pretrained, revision=revision + ("/" + subfolder if subfolder is not None else "")
|
||||
pretrained,
|
||||
revision=revision + ("/" + subfolder if subfolder is not None else ""),
|
||||
).to(self.device)
|
||||
self.gpt2.eval()
|
||||
|
||||
# pretrained tokenizer for neo is broken for now so just hard-coding this to gpt2
|
||||
self.tokenizer = transformers.AutoTokenizer.from_pretrained(
|
||||
pretrained if tokenizer is None else tokenizer, revision=revision, subfolder=subfolder)
|
||||
pretrained if tokenizer is None else tokenizer,
|
||||
revision=revision,
|
||||
subfolder=subfolder,
|
||||
)
|
||||
|
||||
assert isinstance(self.tokenizer, (
|
||||
transformers.GPT2Tokenizer, transformers.GPT2TokenizerFast,
|
||||
transformers.T5Tokenizer, transformers.T5TokenizerFast,
|
||||
)), "this tokenizer has not been checked for compatibility yet!"
|
||||
assert isinstance(
|
||||
self.tokenizer,
|
||||
(
|
||||
transformers.GPT2Tokenizer,
|
||||
transformers.GPT2TokenizerFast,
|
||||
transformers.T5Tokenizer,
|
||||
transformers.T5TokenizerFast,
|
||||
),
|
||||
), "this tokenizer has not been checked for compatibility yet!"
|
||||
|
||||
self.vocab_size = self.tokenizer.vocab_size
|
||||
|
||||
if isinstance(self.tokenizer, (transformers.GPT2Tokenizer, transformers.GPT2TokenizerFast)):
|
||||
assert self.tokenizer.encode('hello\n\nhello') == [31373, 198, 198, 31373], \
|
||||
self.tokenizer.encode('hello\n\nhello')
|
||||
if isinstance(
|
||||
self.tokenizer, (transformers.GPT2Tokenizer, transformers.GPT2TokenizerFast)
|
||||
):
|
||||
assert self.tokenizer.encode("hello\n\nhello") == [
|
||||
31373,
|
||||
198,
|
||||
198,
|
||||
31373,
|
||||
], self.tokenizer.encode("hello\n\nhello")
|
||||
|
||||
# multithreading and batching
|
||||
self.batch_size_per_gpu = batch_size # todo: adaptive batch size
|
||||
@@ -80,7 +106,7 @@ class HFLM(BaseLM):
|
||||
|
||||
def tok_encode(self, string: str):
|
||||
return self.tokenizer.encode(string, add_special_tokens=False)
|
||||
|
||||
|
||||
def tok_decode(self, tokens):
|
||||
return self.tokenizer.decode(tokens)
|
||||
|
||||
@@ -94,13 +120,10 @@ class HFLM(BaseLM):
|
||||
"""
|
||||
with torch.no_grad():
|
||||
return self.gpt2(inps)[0][:, :, :50257]
|
||||
|
||||
|
||||
def _model_generate(self, context, max_length, eos_token_id):
|
||||
return self.gpt2.generate(
|
||||
context,
|
||||
max_length=max_length,
|
||||
eos_token_id=eos_token_id,
|
||||
do_sample=False
|
||||
context, max_length=max_length, eos_token_id=eos_token_id, do_sample=False
|
||||
)
|
||||
|
||||
|
||||
|
||||
+36
-21
@@ -31,22 +31,24 @@ def get_result(response, ctxlen):
|
||||
if top_token != token:
|
||||
is_greedy = False
|
||||
break
|
||||
|
||||
|
||||
return continuation_logprobs, is_greedy
|
||||
|
||||
|
||||
def oa_completion(**kwargs):
|
||||
""" Query OpenAI API for completion.
|
||||
"""Query OpenAI API for completion.
|
||||
|
||||
Retry with back-off until they respond
|
||||
"""
|
||||
import openai
|
||||
|
||||
backoff_time = 3
|
||||
while True:
|
||||
try:
|
||||
return openai.Completion.create(**kwargs)
|
||||
except openai.error.OpenAIError:
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
time.sleep(backoff_time)
|
||||
backoff_time *= 1.5
|
||||
@@ -66,16 +68,19 @@ class GPT3LM(BaseLM):
|
||||
super().__init__()
|
||||
|
||||
import openai
|
||||
|
||||
self.engine = engine
|
||||
self.tokenizer = transformers.GPT2TokenizerFast.from_pretrained('gpt2')
|
||||
self.tokenizer = transformers.GPT2TokenizerFast.from_pretrained("gpt2")
|
||||
|
||||
self.vocab_size = self.tokenizer.vocab_size
|
||||
|
||||
# to make the annoying "Using pad_token, but it is not set yet." error go away
|
||||
self.tokenizer.pad_token = "<|endoftext|>"
|
||||
assert self.tokenizer.encode('hello\n\nhello') == [31373, 198, 198, 31373]
|
||||
assert self.tokenizer.encode("hello\n\nhello") == [31373, 198, 198, 31373]
|
||||
self.truncate = truncate
|
||||
self.end_of_text_token_id = self.tokenizer.convert_tokens_to_ids(["<|endoftext|>"])[0]
|
||||
self.end_of_text_token_id = self.tokenizer.convert_tokens_to_ids(
|
||||
["<|endoftext|>"]
|
||||
)[0]
|
||||
|
||||
# Read from environment variable OPENAI_API_SECRET_KEY
|
||||
openai.api_key = os.environ["OPENAI_API_SECRET_KEY"]
|
||||
@@ -105,7 +110,7 @@ class GPT3LM(BaseLM):
|
||||
|
||||
def tok_encode(self, string: str):
|
||||
return self.tokenizer.encode(string, add_special_tokens=False)
|
||||
|
||||
|
||||
def tok_decode(self, tokens):
|
||||
return self.tokenizer.decode(tokens)
|
||||
|
||||
@@ -118,17 +123,22 @@ class GPT3LM(BaseLM):
|
||||
# we care about and so we need some kind of backup for when it isn't
|
||||
toks = x[1] + x[2]
|
||||
return -len(toks), tuple(toks)
|
||||
|
||||
|
||||
reord = utils.Reorderer(requests, _collate)
|
||||
|
||||
for chunk in tqdm(list(utils.chunks(reord.get_reordered(), self.REQ_CHUNK_SIZE)), disable=disable_tqdm):
|
||||
for chunk in tqdm(
|
||||
list(utils.chunks(reord.get_reordered(), self.REQ_CHUNK_SIZE)),
|
||||
disable=disable_tqdm,
|
||||
):
|
||||
inps = []
|
||||
ctxlens = []
|
||||
for cache_key, context_enc, continuation_enc in chunk:
|
||||
# max_length+1 because the API takes up to 2049 tokens, including the first context token
|
||||
inp = (context_enc + continuation_enc)[-(self.max_length+1):]
|
||||
inp = (context_enc + continuation_enc)[-(self.max_length + 1) :]
|
||||
# TODO: the logic is much simpler if we just look at the length of continuation tokens
|
||||
ctxlen = len(context_enc) - max(0, len(context_enc) + len(continuation_enc) - (self.max_length+1))
|
||||
ctxlen = len(context_enc) - max(
|
||||
0, len(context_enc) + len(continuation_enc) - (self.max_length + 1)
|
||||
)
|
||||
|
||||
inps.append(inp)
|
||||
ctxlens.append(ctxlen)
|
||||
@@ -137,11 +147,14 @@ class GPT3LM(BaseLM):
|
||||
engine=self.engine,
|
||||
prompt=inps,
|
||||
echo=True,
|
||||
max_tokens=0, temperature=0.,
|
||||
max_tokens=0,
|
||||
temperature=0.0,
|
||||
logprobs=10,
|
||||
)
|
||||
|
||||
for resp, ctxlen, (cache_key, context_enc, continuation_enc) in zip(response.choices, ctxlens, chunk):
|
||||
for resp, ctxlen, (cache_key, context_enc, continuation_enc) in zip(
|
||||
response.choices, ctxlens, chunk
|
||||
):
|
||||
answer = get_result(resp, ctxlen)
|
||||
|
||||
res.append(answer)
|
||||
@@ -160,7 +173,7 @@ class GPT3LM(BaseLM):
|
||||
def _collate(x):
|
||||
toks = self.tok_encode(x[0])
|
||||
return len(toks), x[0]
|
||||
|
||||
|
||||
reord = utils.Reorderer(requests, _collate)
|
||||
|
||||
def sameuntil_chunks(xs, size):
|
||||
@@ -172,38 +185,40 @@ class GPT3LM(BaseLM):
|
||||
ret = []
|
||||
lastuntil = x[1]
|
||||
ret.append(x)
|
||||
|
||||
|
||||
if ret:
|
||||
yield ret, lastuntil
|
||||
|
||||
# todo: more intelligent batching for heterogeneous `until`
|
||||
for chunk, until in tqdm(list(sameuntil_chunks(reord.get_reordered(), self.REQ_CHUNK_SIZE))):
|
||||
for chunk, until in tqdm(
|
||||
list(sameuntil_chunks(reord.get_reordered(), self.REQ_CHUNK_SIZE))
|
||||
):
|
||||
inps = []
|
||||
for context, _ in chunk:
|
||||
context_enc = self.tok_encode(context)
|
||||
inp = context_enc[-(self.max_length - self.max_gen_toks):]
|
||||
inp = context_enc[-(self.max_length - self.max_gen_toks) :]
|
||||
inps.append(inp)
|
||||
|
||||
response = oa_completion(
|
||||
engine=self.engine,
|
||||
prompt=inps,
|
||||
max_tokens=self.max_gen_toks,
|
||||
temperature=0.,
|
||||
max_tokens=self.max_gen_toks,
|
||||
temperature=0.0,
|
||||
logprobs=10,
|
||||
stop=until,
|
||||
)
|
||||
|
||||
for resp, (context, until_) in zip(response.choices, chunk):
|
||||
s = resp['text']
|
||||
s = resp["text"]
|
||||
|
||||
for term in until_:
|
||||
s = s.split(term)[0]
|
||||
|
||||
# partial caching
|
||||
self.cache_hook.add_partial("greedy_until", (context, until_), s)
|
||||
|
||||
|
||||
res.append(s)
|
||||
|
||||
|
||||
return reord.get_original(res)
|
||||
|
||||
def _model_call(self, inps):
|
||||
|
||||
+22
-35
@@ -59,8 +59,8 @@ from . import storycloze
|
||||
|
||||
# 6 total
|
||||
gpt3_translation_benchmarks = {
|
||||
"wmt14": ['en-fr', 'fr-en'], # French
|
||||
"wmt16": ['en-ro', 'ro-en', 'de-en', 'en-de'], # German, Romanian
|
||||
"wmt14": ["en-fr", "fr-en"], # French
|
||||
"wmt16": ["en-ro", "ro-en", "de-en", "en-de"], # German, Romanian
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ gpt3_translation_benchmarks = {
|
||||
selected_translation_benchmarks = {
|
||||
**gpt3_translation_benchmarks,
|
||||
"wmt20": sacrebleu.get_langpairs_for_testset("wmt20"),
|
||||
"iwslt17": ['en-ar', 'ar-en'] # Arabic
|
||||
"iwslt17": ["en-ar", "ar-en"], # Arabic
|
||||
}
|
||||
|
||||
# 319 total
|
||||
@@ -92,7 +92,7 @@ TASK_REGISTRY = {
|
||||
"rte": glue.RTE,
|
||||
"qnli": glue.QNLI,
|
||||
"qqp": glue.QQP,
|
||||
#"stsb": glue.STSB, # not implemented yet
|
||||
# "stsb": glue.STSB, # not implemented yet
|
||||
"sst": glue.SST,
|
||||
"wnli": glue.WNLI,
|
||||
# SuperGLUE
|
||||
@@ -103,34 +103,26 @@ TASK_REGISTRY = {
|
||||
"record": superglue.ReCoRD,
|
||||
"wic": superglue.WordsInContext,
|
||||
"wsc": superglue.SGWinogradSchemaChallenge,
|
||||
|
||||
# Order by benchmark/genre?
|
||||
"coqa": coqa.CoQA,
|
||||
"drop": drop.DROP,
|
||||
"lambada": lambada.LAMBADA,
|
||||
"lambada_cloze": lambada_cloze.LAMBADA_cloze,
|
||||
|
||||
# multilingual lambada
|
||||
**lambada_multilingual.construct_tasks(),
|
||||
|
||||
"wikitext": wikitext.WikiText,
|
||||
# "cbt-cn": cbt.CBTCN, # disabled pending context length fix
|
||||
# "cbt-ne": cbt.CBTNE, # disabled pending context length fix
|
||||
|
||||
"piqa": piqa.PiQA,
|
||||
"prost": prost.PROST,
|
||||
"mc_taco": mc_taco.MCTACO,
|
||||
|
||||
# Science related
|
||||
"pubmedqa" : pubmedqa.Pubmed_QA,
|
||||
"sciq" : sciq.SciQ,
|
||||
|
||||
"pubmedqa": pubmedqa.Pubmed_QA,
|
||||
"sciq": sciq.SciQ,
|
||||
"qasper": qasper.QASPER,
|
||||
|
||||
"qa4mre_2011" : qa4mre.QA4MRE_2011,
|
||||
"qa4mre_2012" : qa4mre.QA4MRE_2012,
|
||||
"qa4mre_2013" : qa4mre.QA4MRE_2013,
|
||||
|
||||
"qa4mre_2011": qa4mre.QA4MRE_2011,
|
||||
"qa4mre_2012": qa4mre.QA4MRE_2012,
|
||||
"qa4mre_2013": qa4mre.QA4MRE_2013,
|
||||
"triviaqa": triviaqa.TriviaQA,
|
||||
"arc_easy": arc.ARCEasy,
|
||||
"arc_challenge": arc.ARCChallenge,
|
||||
@@ -142,7 +134,7 @@ TASK_REGISTRY = {
|
||||
"squad2": squad.SQuAD2,
|
||||
"race": race.RACE,
|
||||
# "naturalqs": naturalqs.NaturalQs, # not implemented yet
|
||||
"headqa": headqa.HeadQAEsDeprecated, # for backwards compat - headqa used to default to es
|
||||
"headqa": headqa.HeadQAEsDeprecated, # for backwards compat - headqa used to default to es
|
||||
"headqa_es": headqa.HeadQAEs,
|
||||
"headqa_en": headqa.HeadQAEn,
|
||||
"mathqa": mathqa.MathQA,
|
||||
@@ -152,21 +144,17 @@ TASK_REGISTRY = {
|
||||
"anli_r1": anli.ANLIRound1,
|
||||
"anli_r2": anli.ANLIRound2,
|
||||
"anli_r3": anli.ANLIRound3,
|
||||
|
||||
"ethics_cm": hendrycks_ethics.EthicsCM,
|
||||
"ethics_deontology": hendrycks_ethics.EthicsDeontology,
|
||||
"ethics_justice": hendrycks_ethics.EthicsJustice,
|
||||
"ethics_utilitarianism_original": hendrycks_ethics.EthicsUtilitarianismOriginal,
|
||||
"ethics_utilitarianism": hendrycks_ethics.EthicsUtilitarianism,
|
||||
"ethics_virtue": hendrycks_ethics.EthicsVirtue,
|
||||
|
||||
"truthfulqa_mc": truthfulqa.TruthfulQAMultipleChoice,
|
||||
"truthfulqa_gen": truthfulqa.TruthfulQAGeneration,
|
||||
|
||||
"truthfulqa_mc": truthfulqa.TruthfulQAMultipleChoice,
|
||||
"truthfulqa_gen": truthfulqa.TruthfulQAGeneration,
|
||||
# dialogue
|
||||
"mutual": mutual.MuTual,
|
||||
"mutual_plus": mutual.MuTualPlus,
|
||||
|
||||
# math
|
||||
"math_algebra": hendrycks_math.MathAlgebra,
|
||||
"math_counting_and_prob": hendrycks_math.MathCountingAndProbability,
|
||||
@@ -177,7 +165,6 @@ TASK_REGISTRY = {
|
||||
"math_precalc": hendrycks_math.MathPrecalculus,
|
||||
"math_asdiv": asdiv.Asdiv,
|
||||
"gsm8k": gsm8k.GradeSchoolMath8K,
|
||||
|
||||
# arithmetic
|
||||
"arithmetic_2da": arithmetic.Arithmetic2DPlus,
|
||||
"arithmetic_2ds": arithmetic.Arithmetic2DMinus,
|
||||
@@ -191,22 +178,18 @@ TASK_REGISTRY = {
|
||||
"arithmetic_1dc": arithmetic.Arithmetic1DComposite,
|
||||
# TODO Perhaps make these groups of tasks
|
||||
# e.g. anli, arithmetic, openai_translations, harness_translations
|
||||
|
||||
# hendrycksTest (57 tasks)
|
||||
**hendrycks_test.create_all_tasks(),
|
||||
|
||||
# e.g. wmt14-fr-en
|
||||
**translation.create_tasks_from_benchmarks(gpt3_translation_benchmarks),
|
||||
# chef's selection, mostly wmt20
|
||||
**translation.create_tasks_from_benchmarks(selected_translation_benchmarks),
|
||||
|
||||
# Word Scrambling and Manipulation Tasks
|
||||
"anagrams1": unscramble.Anagrams1,
|
||||
"anagrams2": unscramble.Anagrams2,
|
||||
"cycle_letters": unscramble.CycleLetters,
|
||||
"random_insertion": unscramble.RandomInsertion,
|
||||
"reversed_words": unscramble.ReversedWords,
|
||||
|
||||
# Pile
|
||||
"pile_arxiv": pile.PileArxiv,
|
||||
"pile_books3": pile.PileBooks3,
|
||||
@@ -230,7 +213,6 @@ TASK_REGISTRY = {
|
||||
"pile_ubuntu-irc": pile.PileUbuntuIrc,
|
||||
"pile_wikipedia": pile.PileWikipedia,
|
||||
"pile_youtubesubtitles": pile.PileYoutubeSubtitles,
|
||||
|
||||
# BLiMP
|
||||
"blimp_adjunct_island": blimp.BlimpAdjunctIsland,
|
||||
"blimp_anaphor_gender_agreement": blimp.BlimpAnaphorGenderAgreement,
|
||||
@@ -299,7 +281,6 @@ TASK_REGISTRY = {
|
||||
"blimp_wh_vs_that_no_gap_long_distance": blimp.BlimpWhVsThatNoGapLongDistance,
|
||||
"blimp_wh_vs_that_with_gap": blimp.BlimpWhVsThatWithGap,
|
||||
"blimp_wh_vs_that_with_gap_long_distance": blimp.BlimpWhVsThatWithGapLongDistance,
|
||||
|
||||
# Requires manual download of data.
|
||||
# "storycloze_2016": storycloze.StoryCloze2016,
|
||||
# "storycloze_2018": storycloze.StoryCloze2018,
|
||||
@@ -323,19 +304,25 @@ def get_task_name_from_object(task_object):
|
||||
for name, class_ in TASK_REGISTRY.items():
|
||||
if class_ is task_object:
|
||||
return name
|
||||
|
||||
|
||||
# this gives a mechanism for non-registered tasks to have a custom name anyways when reporting
|
||||
return task_object.EVAL_HARNESS_NAME if hasattr(task_object, "EVAL_HARNESS_NAME") else type(task_object).__name__
|
||||
return (
|
||||
task_object.EVAL_HARNESS_NAME
|
||||
if hasattr(task_object, "EVAL_HARNESS_NAME")
|
||||
else type(task_object).__name__
|
||||
)
|
||||
|
||||
|
||||
def get_task_dict(task_name_list: List[Union[str, lm_eval.base.Task]]):
|
||||
task_name_dict = {
|
||||
task_name: get_task(task_name)()
|
||||
for task_name in task_name_list if isinstance(task_name, str)
|
||||
for task_name in task_name_list
|
||||
if isinstance(task_name, str)
|
||||
}
|
||||
task_name_from_object_dict = {
|
||||
get_task_name_from_object(task_object): task_object
|
||||
for task_object in task_name_list if not isinstance(task_object, str)
|
||||
for task_object in task_name_list
|
||||
if not isinstance(task_object, str)
|
||||
}
|
||||
assert set(task_name_dict.keys()).isdisjoint(set(task_name_from_object_dict.keys()))
|
||||
return {**task_name_dict, **task_name_from_object_dict}
|
||||
|
||||
+23
-24
@@ -61,10 +61,15 @@ class ANLIBase(Task):
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
# OA does this a bit weirdly: they prepend "anli 1: anli 1: " to the beginning
|
||||
# of the prompt (yes, repeating it!). also, " True, False, or Neither?" is directly
|
||||
# appended onto the question, with no "Answer:" or even a newline. Do we *really*
|
||||
# of the prompt (yes, repeating it!). also, " True, False, or Neither?" is directly
|
||||
# appended onto the question, with no "Answer:" or even a newline. Do we *really*
|
||||
# want to do it exactly as OA did?
|
||||
return doc['premise'] + '\nQuestion: ' + doc['hypothesis'] + ' True, False, or Neither?\nAnswer:'
|
||||
return (
|
||||
doc["premise"]
|
||||
+ "\nQuestion: "
|
||||
+ doc["hypothesis"]
|
||||
+ " True, False, or Neither?\nAnswer:"
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
@@ -76,27 +81,27 @@ class ANLIBase(Task):
|
||||
# True = entailment
|
||||
# False = contradiction
|
||||
# Neither = neutral
|
||||
return " " + ["True", "Neither", "False"][doc['label']]
|
||||
return " " + ["True", "Neither", "False"][doc["label"]]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
ll_true, _ = rf.loglikelihood(ctx, " True")
|
||||
ll_neither, _ = rf.loglikelihood(ctx, " Neither")
|
||||
ll_false, _ = rf.loglikelihood(ctx, " False")
|
||||
ll_true, _ = rf.loglikelihood(ctx, " True")
|
||||
ll_neither, _ = rf.loglikelihood(ctx, " Neither")
|
||||
ll_false, _ = rf.loglikelihood(ctx, " False")
|
||||
return ll_true, ll_neither, ll_false
|
||||
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
@@ -106,29 +111,23 @@ class ANLIBase(Task):
|
||||
"""
|
||||
gold = doc["label"]
|
||||
pred = np.argmax(results)
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class ANLIRound1(ANLIBase):
|
||||
|
||||
@@ -49,7 +49,7 @@ class Arithmetic(Task):
|
||||
|
||||
def test_docs(self):
|
||||
return NotImplemented
|
||||
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc["context"]
|
||||
|
||||
@@ -67,10 +67,8 @@ class Arithmetic(Task):
|
||||
return is_prediction
|
||||
|
||||
def process_results(self, doc, results):
|
||||
is_prediction, = results
|
||||
return {
|
||||
"acc": is_prediction
|
||||
}
|
||||
(is_prediction,) = results
|
||||
return {"acc": is_prediction}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
@@ -78,9 +76,7 @@ class Arithmetic(Task):
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class Arithmetic2DPlus(Arithmetic):
|
||||
|
||||
+12
-19
@@ -54,48 +54,41 @@ class Asdiv(Task):
|
||||
def test_docs(self):
|
||||
raise NotImplementedError("This dataset has no test docs")
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert num_fewshot == 0, "ASDiv is intended only for the zero-shot setting."
|
||||
return super().fewshot_context(
|
||||
doc=doc,
|
||||
num_fewshot=num_fewshot,
|
||||
rnd=rnd,
|
||||
description=description
|
||||
doc=doc, num_fewshot=num_fewshot, rnd=rnd, description=description
|
||||
)
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
# TODO: add solution-type
|
||||
return doc['body'] + '\n' + 'Question:' + doc['question'] + '\n' + 'Answer:'
|
||||
return doc["body"] + "\n" + "Question:" + doc["question"] + "\n" + "Answer:"
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['body'] + " " + doc['question']
|
||||
return doc["body"] + " " + doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
# TODO: add formula
|
||||
|
||||
answer = doc['answer'].split(' (')[0]
|
||||
answer = doc["answer"].split(" (")[0]
|
||||
return " " + answer
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ll, is_greedy = rf.loglikelihood(ctx, self.doc_to_target(doc))
|
||||
return ll, is_greedy
|
||||
|
||||
|
||||
def process_results(self, doc, results):
|
||||
ll, is_greedy = results
|
||||
|
||||
return {
|
||||
'acc': int(is_greedy)
|
||||
}
|
||||
|
||||
return {"acc": int(is_greedy)}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
+10
-4
@@ -37,7 +37,7 @@ class BlimpTask(Task):
|
||||
|
||||
def has_training_docs(self):
|
||||
return False
|
||||
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
@@ -50,9 +50,13 @@ class BlimpTask(Task):
|
||||
# trained on this data.
|
||||
return self.dataset["train"]
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert num_fewshot == 0
|
||||
assert rnd is not None, "A `random.Random` generator argument must be provided to `rnd`"
|
||||
assert (
|
||||
rnd is not None
|
||||
), "A `random.Random` generator argument must be provided to `rnd`"
|
||||
assert not provide_description, (
|
||||
"The `provide_description` arg will be removed in future versions. To prepend "
|
||||
"a custom description to the context, supply the corresponding string via the "
|
||||
@@ -60,7 +64,9 @@ class BlimpTask(Task):
|
||||
)
|
||||
if provide_description is not None:
|
||||
# nudge people to not specify it at all
|
||||
print("WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict")
|
||||
print(
|
||||
"WARNING: provide_description is deprecated and will be removed in a future version in favor of description_dict"
|
||||
)
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
+8
-12
@@ -2,7 +2,7 @@
|
||||
The Children’s Book Test (CBT) from the paper:
|
||||
https://research.fb.com/wp-content/uploads/2016/11/the_goldilocks_principle_reading_children_s_books_with_explicit_memory_representations.pdf
|
||||
|
||||
The Children's Book Test (CBT) is test of how well language models capture
|
||||
The Children's Book Test (CBT) is test of how well language models capture
|
||||
meaning in children's books. Unlike standard language modelling benchmarks,
|
||||
it distinguishes the task of predicting syntactic function words from that
|
||||
of predicting lower-frequency words, which carry greater semantic content.
|
||||
@@ -19,7 +19,7 @@ from lm_eval.metrics import mean
|
||||
|
||||
_CITATION = """
|
||||
@misc{hill2016goldilocks,
|
||||
title={The Goldilocks Principle: Reading Children's Books with Explicit Memory Representations},
|
||||
title={The Goldilocks Principle: Reading Children's Books with Explicit Memory Representations},
|
||||
author={Felix Hill and Antoine Bordes and Sumit Chopra and Jason Weston},
|
||||
year={2016},
|
||||
eprint={1511.02301},
|
||||
@@ -86,7 +86,9 @@ class CBTBase(Task):
|
||||
return ""
|
||||
|
||||
def fewshot_examples(self, k, rnd):
|
||||
assert k == 0, f"CBT is only implemented for the zero-shot setting. Given k={k}."
|
||||
assert (
|
||||
k == 0
|
||||
), f"CBT is only implemented for the zero-shot setting. Given k={k}."
|
||||
return super().fewshot_examples(k, rnd)
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
@@ -120,9 +122,7 @@ class CBTBase(Task):
|
||||
"""
|
||||
gold = doc["options"].index(doc["answer"])
|
||||
pred = np.argmax(results)
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
@@ -130,9 +130,7 @@ class CBTBase(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
@@ -140,9 +138,7 @@ class CBTBase(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class CBTCN(CBTBase):
|
||||
|
||||
+37
-28
@@ -2,9 +2,9 @@
|
||||
CoQA: A Conversational Question Answering Challenge
|
||||
https://arxiv.org/pdf/1808.07042.pdf
|
||||
|
||||
CoQA is a large-scale dataset for building Conversational Question Answering
|
||||
systems. The goal of the CoQA challenge is to measure the ability of machines to
|
||||
understand a text passage and answer a series of interconnected questions that
|
||||
CoQA is a large-scale dataset for building Conversational Question Answering
|
||||
systems. The goal of the CoQA challenge is to measure the ability of machines to
|
||||
understand a text passage and answer a series of interconnected questions that
|
||||
appear in a conversation.
|
||||
|
||||
Homepage: https://stanfordnlp.github.io/coqa/
|
||||
@@ -52,15 +52,17 @@ class CoQA(Task):
|
||||
pass
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
# Given a passage p, the conversation history {q1, a1, . . . qi−1, ai−1}
|
||||
# Given a passage p, the conversation history {q1, a1, . . . qi−1, ai−1}
|
||||
# and a question qi, the task is to predict the answer ai
|
||||
doc_text = doc["story"] + '\n\n'
|
||||
for (q, a) in zip_longest(doc["questions"]["input_text"], doc["answers"]["input_text"][:-1]): # omit target answer ai
|
||||
doc_text = doc["story"] + "\n\n"
|
||||
for (q, a) in zip_longest(
|
||||
doc["questions"]["input_text"], doc["answers"]["input_text"][:-1]
|
||||
): # omit target answer ai
|
||||
question = f"Q: {q}\n\n"
|
||||
answer = f"A: {a}\n\n" if a is not None else "A:"
|
||||
doc_text += question + answer
|
||||
return doc_text
|
||||
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
@@ -73,28 +75,30 @@ class CoQA(Task):
|
||||
answers = []
|
||||
answer_forturn = doc["answers"]["input_text"][turn_id - 1]
|
||||
answers.append(answer_forturn)
|
||||
|
||||
|
||||
additional_answers = doc.get("additional_answers")
|
||||
if additional_answers:
|
||||
for key in additional_answers:
|
||||
additional_answer_for_turn = additional_answers[key]["input_text"][turn_id - 1]
|
||||
additional_answer_for_turn = additional_answers[key]["input_text"][
|
||||
turn_id - 1
|
||||
]
|
||||
if additional_answer_for_turn.lower() not in map(str.lower, answers):
|
||||
answers.append(additional_answer_for_turn)
|
||||
return answers
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_answer_choice(self, raw_text):
|
||||
# Function maps answers to CoQA answer categories
|
||||
# ~ 1/5 of the CoQA answers are Yes/No
|
||||
# ~ 1/5 of the CoQA answers are Yes/No
|
||||
# ~ 2/3 of the CoQA answers are span-based
|
||||
# (answers overlap with the passage ignoring punctuation and case mismatch)
|
||||
if raw_text == "unknown":
|
||||
return '0'
|
||||
return "0"
|
||||
if squad_metrics.normalize_answer(raw_text) == "yes":
|
||||
return '1'
|
||||
return "1"
|
||||
if squad_metrics.normalize_answer(raw_text) == "no":
|
||||
return '2'
|
||||
return '3' # Not a yes/no question
|
||||
return "2"
|
||||
return "3" # Not a yes/no question
|
||||
|
||||
@staticmethod
|
||||
def compute_scores(gold_list, pred):
|
||||
@@ -104,40 +108,45 @@ class CoQA(Task):
|
||||
em_sum = 0.0
|
||||
if len(gold_list) > 1:
|
||||
for i in range(len(gold_list)):
|
||||
gold_answers = gold_list[0:i] + gold_list[i + 1:]
|
||||
gold_answers = gold_list[0:i] + gold_list[i + 1 :]
|
||||
# predictions compared against (n) golds and take maximum
|
||||
em_sum += max(squad_metrics.compute_exact(a, pred) for a in gold_answers)
|
||||
em_sum += max(
|
||||
squad_metrics.compute_exact(a, pred) for a in gold_answers
|
||||
)
|
||||
f1_sum += max(squad_metrics.compute_f1(a, pred) for a in gold_answers)
|
||||
else:
|
||||
em_sum += max(squad_metrics.compute_exact(a, pred) for a in gold_list)
|
||||
f1_sum += max(squad_metrics.compute_f1(a, pred) for a in gold_list)
|
||||
|
||||
return {'em': em_sum / max(1, len(gold_list)), 'f1': f1_sum / max(1, len(gold_list))}
|
||||
return {
|
||||
"em": em_sum / max(1, len(gold_list)),
|
||||
"f1": f1_sum / max(1, len(gold_list)),
|
||||
}
|
||||
|
||||
def doc_to_target(self, doc, turnid=None):
|
||||
# Default to prediction of last turn.
|
||||
if turnid is None:
|
||||
turnid = len(doc["questions"]["input_text"])
|
||||
raw_text = doc['answers']["input_text"][turnid - 1]
|
||||
raw_text = doc["answers"]["input_text"][turnid - 1]
|
||||
return " " + raw_text
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
cont_request = rf.greedy_until(ctx, ['\nQ:'])
|
||||
cont_request = rf.greedy_until(ctx, ["\nQ:"])
|
||||
return cont_request
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
@@ -147,13 +156,13 @@ class CoQA(Task):
|
||||
"""
|
||||
turn_id = len(doc["questions"]["input_text"])
|
||||
gold_list = self.get_answers(doc, turn_id)
|
||||
pred = results[0].strip().split('\n')[0]
|
||||
pred = results[0].strip().split("\n")[0]
|
||||
|
||||
scores = self.compute_scores(gold_list, pred)
|
||||
|
||||
return {
|
||||
"f1": scores['f1'],
|
||||
"em": scores['em'],
|
||||
"f1": scores["f1"],
|
||||
"em": scores["em"],
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
|
||||
+35
-29
@@ -2,8 +2,8 @@
|
||||
DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs
|
||||
https://aclanthology.org/attachments/N19-1246.Supplementary.pdf
|
||||
|
||||
DROP is a QA dataset which tests comprehensive understanding of paragraphs. In
|
||||
this crowdsourced, adversarially-created, 96k question-answering benchmark, a
|
||||
DROP is a QA dataset which tests comprehensive understanding of paragraphs. In
|
||||
this crowdsourced, adversarially-created, 96k question-answering benchmark, a
|
||||
system must resolve multiple references in a question, map them onto a paragraph,
|
||||
and perform discrete operations over them (such as addition, counting, or sorting).
|
||||
|
||||
@@ -24,7 +24,7 @@ from lm_eval.metrics import mean
|
||||
|
||||
_CITATION = """
|
||||
@misc{dua2019drop,
|
||||
title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs},
|
||||
title={DROP: A Reading Comprehension Benchmark Requiring Discrete Reasoning Over Paragraphs},
|
||||
author={Dheeru Dua and Yizhong Wang and Pradeep Dasigi and Gabriel Stanovsky and Sameer Singh and Matt Gardner},
|
||||
year={2019},
|
||||
eprint={1903.00161},
|
||||
@@ -70,21 +70,26 @@ class DROP(Task):
|
||||
@classmethod
|
||||
def get_answers(cls, qa):
|
||||
def _flatten_validated_answers(validated_answers):
|
||||
""" Flattens a dict of lists of validated answers.
|
||||
"""Flattens a dict of lists of validated answers.
|
||||
{"number": ['1', '8'], ...}
|
||||
-> [{"number": ['1'], ...}, {"number": ['8'], ...}]
|
||||
"""
|
||||
vas = []
|
||||
for i in range(len(validated_answers["number"])):
|
||||
vas.append({
|
||||
"number": validated_answers["number"][i],
|
||||
"date": validated_answers["date"][i],
|
||||
"spans": validated_answers["spans"][i],
|
||||
})
|
||||
vas.append(
|
||||
{
|
||||
"number": validated_answers["number"][i],
|
||||
"date": validated_answers["date"][i],
|
||||
"spans": validated_answers["spans"][i],
|
||||
}
|
||||
)
|
||||
return vas
|
||||
|
||||
answers = []
|
||||
answers_set = set()
|
||||
candidates = [qa["answer"]] + _flatten_validated_answers(qa["validated_answers"])
|
||||
candidates = [qa["answer"]] + _flatten_validated_answers(
|
||||
qa["validated_answers"]
|
||||
)
|
||||
for candidate in candidates:
|
||||
answer = cls.parse_answer(candidate)
|
||||
if answer in answers_set:
|
||||
@@ -100,9 +105,11 @@ class DROP(Task):
|
||||
return (str(answer["number"]),)
|
||||
if answer["spans"] != []:
|
||||
return tuple(answer["spans"])
|
||||
return (" ".join([answer["date"]["day"],
|
||||
answer["date"]["month"],
|
||||
answer["date"]["year"]]).strip(),)
|
||||
return (
|
||||
" ".join(
|
||||
[answer["date"]["day"], answer["date"]["month"], answer["date"]["year"]]
|
||||
).strip(),
|
||||
)
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return f"Passage: {doc['passage']}\nQuestion: {doc['question']}\nAnswer:"
|
||||
@@ -111,7 +118,7 @@ class DROP(Task):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['passage'] + " " + doc['question']
|
||||
return doc["passage"] + " " + doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + ", ".join(doc["answers"][0])
|
||||
@@ -148,10 +155,7 @@ class DROP(Task):
|
||||
if gold_answer[0].strip():
|
||||
max_em = max(max_em, exact_match)
|
||||
max_f1 = max(max_f1, f1_score)
|
||||
return {
|
||||
"em": max_em,
|
||||
"f1": max_f1
|
||||
}
|
||||
return {"em": max_em, "f1": max_f1}
|
||||
|
||||
def get_metrics(self, predicted, gold):
|
||||
"""
|
||||
@@ -164,7 +168,9 @@ class DROP(Task):
|
||||
predicted_bags = self._answer_to_bags(predicted)
|
||||
gold_bags = self._answer_to_bags(gold)
|
||||
|
||||
if set(predicted_bags[0]) == set(gold_bags[0]) and len(predicted_bags[0]) == len(gold_bags[0]):
|
||||
if set(predicted_bags[0]) == set(gold_bags[0]) and len(
|
||||
predicted_bags[0]
|
||||
) == len(gold_bags[0]):
|
||||
exact_match = 1.0
|
||||
else:
|
||||
exact_match = 0.0
|
||||
@@ -196,7 +202,9 @@ class DROP(Task):
|
||||
for gold_index, gold_item in enumerate(gold):
|
||||
for pred_index, pred_item in enumerate(predicted):
|
||||
if self._match_numbers_if_present(gold_item, pred_item):
|
||||
scores[gold_index, pred_index] = self._compute_f1(pred_item, gold_item)
|
||||
scores[gold_index, pred_index] = self._compute_f1(
|
||||
pred_item, gold_item
|
||||
)
|
||||
row_ind, col_ind = linear_sum_assignment(-scores)
|
||||
|
||||
max_scores = np.zeros([max(len(gold), len(predicted))])
|
||||
@@ -262,7 +270,11 @@ class DROP(Task):
|
||||
|
||||
def _normalize(self, answer):
|
||||
tokens = [
|
||||
self._white_space_fix(self._remove_articles(self._fix_number(self._remove_punc(token.lower()))))
|
||||
self._white_space_fix(
|
||||
self._remove_articles(
|
||||
self._fix_number(self._remove_punc(token.lower()))
|
||||
)
|
||||
)
|
||||
for token in self._tokenize(answer)
|
||||
]
|
||||
tokens = [token for token in tokens if token.strip()]
|
||||
@@ -275,10 +287,7 @@ class DROP(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"em": mean,
|
||||
"f1": mean
|
||||
}
|
||||
return {"em": mean, "f1": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
@@ -286,7 +295,4 @@ class DROP(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"em": True,
|
||||
"f1": True
|
||||
}
|
||||
return {"em": True, "f1": True}
|
||||
|
||||
+44
-87
@@ -68,7 +68,9 @@ class CoLA(Task):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "{}\nQuestion: Does this sentence make sense?\nAnswer:".format(doc["sentence"])
|
||||
return "{}\nQuestion: Does this sentence make sense?\nAnswer:".format(
|
||||
doc["sentence"]
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
@@ -88,19 +90,13 @@ class CoLA(Task):
|
||||
ll_true, ll_false = results
|
||||
pred = ll_true > ll_false
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"mcc": (gold, pred)
|
||||
}
|
||||
return {"mcc": (gold, pred)}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"mcc": True
|
||||
}
|
||||
return {"mcc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"mcc": matthews_corrcoef
|
||||
}
|
||||
return {"mcc": matthews_corrcoef}
|
||||
|
||||
|
||||
class SST(Task):
|
||||
@@ -142,19 +138,13 @@ class SST(Task):
|
||||
ll_positive, ll_negative = results
|
||||
pred = ll_positive > ll_negative
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
# Inference Tasks
|
||||
@@ -190,7 +180,8 @@ class MNLI(Task):
|
||||
def doc_to_text(self, doc):
|
||||
return "{}\nQuestion: {} True, False or Neither?\nAnswer:".format(
|
||||
doc["premise"],
|
||||
doc["hypothesis"].strip() + ('' if doc["hypothesis"].strip().endswith('.') else '.'),
|
||||
doc["hypothesis"].strip()
|
||||
+ ("" if doc["hypothesis"].strip().endswith(".") else "."),
|
||||
)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
@@ -208,19 +199,13 @@ class MNLI(Task):
|
||||
def process_results(self, doc, results):
|
||||
gold = doc["label"]
|
||||
pred = np.argmax(results)
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
class MNLIMismatched(MNLI):
|
||||
@@ -258,9 +243,11 @@ class QNLI(Task):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "{}\n{}\nQuestion: Does this response answer the question?\nAnswer:".format(
|
||||
doc["question"],
|
||||
doc["sentence"],
|
||||
return (
|
||||
"{}\n{}\nQuestion: Does this response answer the question?\nAnswer:".format(
|
||||
doc["question"],
|
||||
doc["sentence"],
|
||||
)
|
||||
)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
@@ -277,19 +264,13 @@ class QNLI(Task):
|
||||
ll_yes, ll_no = results
|
||||
pred = ll_no > ll_yes
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
class WNLI(Task):
|
||||
@@ -334,19 +315,13 @@ class WNLI(Task):
|
||||
ll_true, ll_false = results
|
||||
pred = ll_true > ll_false
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
class RTE(Task):
|
||||
@@ -391,19 +366,13 @@ class RTE(Task):
|
||||
ll_true, ll_false = results
|
||||
pred = ll_false > ll_true
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
# Similarity and Paraphrase Tasks
|
||||
@@ -455,16 +424,10 @@ class MRPC(Task):
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True,
|
||||
"f1": True
|
||||
}
|
||||
return {"acc": True, "f1": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean,
|
||||
"f1": f1_score
|
||||
}
|
||||
return {"acc": mean, "f1": f1_score}
|
||||
|
||||
|
||||
class QQP(Task):
|
||||
@@ -513,16 +476,10 @@ class QQP(Task):
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True,
|
||||
"f1": True
|
||||
}
|
||||
return {"acc": True, "f1": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean,
|
||||
"f1": f1_score
|
||||
}
|
||||
return {"acc": mean, "f1": f1_score}
|
||||
|
||||
|
||||
class STSB(Task):
|
||||
@@ -560,22 +517,22 @@ class STSB(Task):
|
||||
return " {}".format(doc["label"])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
@@ -584,22 +541,22 @@ class STSB(Task):
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
+14
-20
@@ -2,14 +2,14 @@
|
||||
"Training Verifiers to Solve Math Word Problems"
|
||||
https://arxiv.org/abs/2110.14168
|
||||
|
||||
State-of-the-art language models can match human performance on many tasks, but
|
||||
they still struggle to robustly perform multi-step mathematical reasoning. To
|
||||
State-of-the-art language models can match human performance on many tasks, but
|
||||
they still struggle to robustly perform multi-step mathematical reasoning. To
|
||||
diagnose the failures of current models and support research, we introduce GSM8K,
|
||||
a dataset of 8.5K high quality linguistically diverse grade school math word problems.
|
||||
We find that even the largest transformer models fail to achieve high test performance,
|
||||
We find that even the largest transformer models fail to achieve high test performance,
|
||||
despite the conceptual simplicity of this problem distribution.
|
||||
|
||||
NOTE: See the official implementation of the task:
|
||||
NOTE: See the official implementation of the task:
|
||||
https://github.com/openai/grade-school-math/blob/master/grade_school_math/calculator.py
|
||||
for how to make use of the dataset's calculator annotations in your language
|
||||
model's sample/generation function.
|
||||
@@ -64,13 +64,13 @@ class GradeSchoolMath8K(Task):
|
||||
return self.dataset["test"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Question: " + doc['question'] + '\nAnswer:'
|
||||
return "Question: " + doc["question"] + "\nAnswer:"
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + doc['answer']
|
||||
return " " + doc["answer"]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
@@ -80,10 +80,10 @@ class GradeSchoolMath8K(Task):
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# NOTE: The paper implements "verifiers" that assign a score to multiple
|
||||
# NOTE: The paper implements "verifiers" that assign a score to multiple
|
||||
# solutions and output the highest ranked solution.
|
||||
completion = rf.greedy_until(ctx, ['\n'])
|
||||
return completion
|
||||
completion = rf.greedy_until(ctx, ["\n"])
|
||||
return completion
|
||||
|
||||
def _extract_answer(self, completion):
|
||||
match = ANS_RE.search(completion)
|
||||
@@ -97,7 +97,7 @@ class GradeSchoolMath8K(Task):
|
||||
def _is_correct(self, completion, answer):
|
||||
gold = self._extract_answer(answer)
|
||||
assert gold != INVALID_ANS, "No ground truth answer found in the document."
|
||||
return self._extract_answer(completion) == gold
|
||||
return self._extract_answer(completion) == gold
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
@@ -111,9 +111,7 @@ class GradeSchoolMath8K(Task):
|
||||
"""
|
||||
completion = results[0]
|
||||
answer = doc["answer"]
|
||||
return {
|
||||
"acc": self._is_correct(completion, answer)
|
||||
}
|
||||
return {"acc": self._is_correct(completion, answer)}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
@@ -121,9 +119,7 @@ class GradeSchoolMath8K(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
@@ -131,6 +127,4 @@ class GradeSchoolMath8K(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Interpretable Multi-Step Reasoning with Knowledge Extraction on Complex Healthcare Question Answering
|
||||
https://aclanthology.org/P19-1092.pdf
|
||||
|
||||
HEAD-QA is a multi-choice HEAlthcare Dataset. The questions come from exams to
|
||||
HEAD-QA is a multi-choice HEAlthcare Dataset. The questions come from exams to
|
||||
access a specialized position in the Spanish healthcare system, and are challenging
|
||||
even for highly specialized humans.
|
||||
|
||||
@@ -15,7 +15,7 @@ from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
_CITATION = """
|
||||
@misc{liu2020interpretable,
|
||||
title={Interpretable Multi-Step Reasoning with Knowledge Extraction on Complex Healthcare Question Answering},
|
||||
title={Interpretable Multi-Step Reasoning with Knowledge Extraction on Complex Healthcare Question Answering},
|
||||
author={Ye Liu and Shaika Chowdhury and Chenwei Zhang and Cornelia Caragea and Philip S. Yu},
|
||||
year={2020},
|
||||
eprint={2008.02434},
|
||||
@@ -82,4 +82,6 @@ class HeadQAEsDeprecated(HeadQABase):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
print("WARNING: headqa is deprecated. Please use headqa_es or headqa_en instead. See https://github.com/EleutherAI/lm-evaluation-harness/pull/240 for more info.")
|
||||
print(
|
||||
"WARNING: headqa is deprecated. Please use headqa_es or headqa_en instead. See https://github.com/EleutherAI/lm-evaluation-harness/pull/240 for more info."
|
||||
)
|
||||
|
||||
+77
-77
@@ -1,77 +1,77 @@
|
||||
"""
|
||||
HellaSwag: Can a Machine Really Finish Your Sentence?
|
||||
https://arxiv.org/pdf/1905.07830.pdf
|
||||
|
||||
Hellaswag is a commonsense inference challenge dataset. Though its questions are
|
||||
trivial for humans (>95% accuracy), state-of-the-art models struggle (<48%). This is
|
||||
achieved via Adversarial Filtering (AF), a data collection paradigm wherein a
|
||||
series of discriminators iteratively select an adversarial set of machine-generated
|
||||
wrong answers. AF proves to be surprisingly robust. The key insight is to scale up
|
||||
the length and complexity of the dataset examples towards a critical 'Goldilocks'
|
||||
zone wherein generated text is ridiculous to humans, yet often misclassified by
|
||||
state-of-the-art models.
|
||||
|
||||
Homepage: https://rowanzellers.com/hellaswag/
|
||||
"""
|
||||
import re
|
||||
from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@inproceedings{zellers2019hellaswag,
|
||||
title={HellaSwag: Can a Machine Really Finish Your Sentence?},
|
||||
author={Zellers, Rowan and Holtzman, Ari and Bisk, Yonatan and Farhadi, Ali and Choi, Yejin},
|
||||
booktitle ={Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics},
|
||||
year={2019}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class HellaSwag(MultipleChoiceTask):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "hellaswag"
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
ctx = doc["ctx_a"] + " " + doc["ctx_b"].capitalize()
|
||||
out_doc = {
|
||||
"query": self.preprocess(doc['activity_label'] + ': ' + ctx),
|
||||
"choices": [self.preprocess(ending) for ending in doc['endings']],
|
||||
"gold": int(doc['label']),
|
||||
}
|
||||
return out_doc
|
||||
|
||||
@classmethod
|
||||
def preprocess(cls, text):
|
||||
text = text.strip()
|
||||
# NOTE: Brackets are artifacts of the WikiHow dataset portion of HellaSwag.
|
||||
text = text.replace(" [title]", ". ")
|
||||
text = re.sub('\\[.*?\\]', '', text)
|
||||
text = text.replace(" ", " ")
|
||||
return text
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["query"]
|
||||
"""
|
||||
HellaSwag: Can a Machine Really Finish Your Sentence?
|
||||
https://arxiv.org/pdf/1905.07830.pdf
|
||||
|
||||
Hellaswag is a commonsense inference challenge dataset. Though its questions are
|
||||
trivial for humans (>95% accuracy), state-of-the-art models struggle (<48%). This is
|
||||
achieved via Adversarial Filtering (AF), a data collection paradigm wherein a
|
||||
series of discriminators iteratively select an adversarial set of machine-generated
|
||||
wrong answers. AF proves to be surprisingly robust. The key insight is to scale up
|
||||
the length and complexity of the dataset examples towards a critical 'Goldilocks'
|
||||
zone wherein generated text is ridiculous to humans, yet often misclassified by
|
||||
state-of-the-art models.
|
||||
|
||||
Homepage: https://rowanzellers.com/hellaswag/
|
||||
"""
|
||||
import re
|
||||
from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@inproceedings{zellers2019hellaswag,
|
||||
title={HellaSwag: Can a Machine Really Finish Your Sentence?},
|
||||
author={Zellers, Rowan and Holtzman, Ari and Bisk, Yonatan and Farhadi, Ali and Choi, Yejin},
|
||||
booktitle ={Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics},
|
||||
year={2019}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class HellaSwag(MultipleChoiceTask):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "hellaswag"
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
ctx = doc["ctx_a"] + " " + doc["ctx_b"].capitalize()
|
||||
out_doc = {
|
||||
"query": self.preprocess(doc["activity_label"] + ": " + ctx),
|
||||
"choices": [self.preprocess(ending) for ending in doc["endings"]],
|
||||
"gold": int(doc["label"]),
|
||||
}
|
||||
return out_doc
|
||||
|
||||
@classmethod
|
||||
def preprocess(cls, text):
|
||||
text = text.strip()
|
||||
# NOTE: Brackets are artifacts of the WikiHow dataset portion of HellaSwag.
|
||||
text = text.replace(" [title]", ". ")
|
||||
text = re.sub("\\[.*?\\]", "", text)
|
||||
text = text.replace(" ", " ")
|
||||
return text
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
@@ -108,19 +108,13 @@ class EthicsCM(Ethics):
|
||||
ll_yes, ll_no = results
|
||||
pred = ll_yes > ll_no
|
||||
gold = bool(int(doc["label"]))
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class EthicsDeontology(Ethics):
|
||||
@@ -129,7 +123,9 @@ class EthicsDeontology(Ethics):
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
prompt = " ".join([doc["scenario"], doc["excuse"]])
|
||||
return "Question: Would most people believe this reasonable or unreasonable to say? \"{}\"\nAnswer:".format(prompt)
|
||||
return 'Question: Would most people believe this reasonable or unreasonable to say? "{}"\nAnswer:'.format(
|
||||
prompt
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
@@ -149,30 +145,27 @@ class EthicsDeontology(Ethics):
|
||||
def process_results(self, doc, results):
|
||||
pred = np.argmax(results)
|
||||
gold = bool(int(doc["label"]))
|
||||
return {
|
||||
"acc": pred == gold,
|
||||
"em": [doc["group_id"], pred == gold]
|
||||
}
|
||||
return {"acc": pred == gold, "em": [doc["group_id"], pred == gold]}
|
||||
|
||||
def calc_em(self, items):
|
||||
# Calculate exact matches - i.e. all in a pair of 4 are correct
|
||||
# NOTE: `items` is a tuple of (doc["group_id"], is_correct)
|
||||
preds_sort = sorted(items, key=lambda x: x[0])
|
||||
em_sums = [int(preds_sort[4*i][1]) + int(preds_sort[4*i+1][1]) + int(preds_sort[4*i+2][1]) + int(preds_sort[4*i+3][1]) for i in range(len(preds_sort) // 4)]
|
||||
em_sums = [
|
||||
int(preds_sort[4 * i][1])
|
||||
+ int(preds_sort[4 * i + 1][1])
|
||||
+ int(preds_sort[4 * i + 2][1])
|
||||
+ int(preds_sort[4 * i + 3][1])
|
||||
for i in range(len(preds_sort) // 4)
|
||||
]
|
||||
em_cors = [em_sums[i] == 4 for i in range(len(em_sums))]
|
||||
return mean(em_cors)
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean,
|
||||
'em': self.calc_em
|
||||
}
|
||||
return {"acc": mean, "em": self.calc_em}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True,
|
||||
'em': True
|
||||
}
|
||||
return {"acc": True, "em": True}
|
||||
|
||||
|
||||
class EthicsJustice(Ethics):
|
||||
@@ -180,7 +173,9 @@ class EthicsJustice(Ethics):
|
||||
DATASET_NAME = "justice"
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Question: Would most people believe this reasonable or unreasonable to say? \"{}\"\nAnswer:".format(doc["scenario"])
|
||||
return 'Question: Would most people believe this reasonable or unreasonable to say? "{}"\nAnswer:'.format(
|
||||
doc["scenario"]
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
@@ -200,30 +195,27 @@ class EthicsJustice(Ethics):
|
||||
def process_results(self, doc, results):
|
||||
pred = np.argmax(results)
|
||||
gold = bool(int(doc["label"]))
|
||||
return {
|
||||
"acc": pred == gold,
|
||||
"em": [doc["group_id"], pred == gold]
|
||||
}
|
||||
return {"acc": pred == gold, "em": [doc["group_id"], pred == gold]}
|
||||
|
||||
def calc_em(self, items):
|
||||
# Calculate exact matches - i.e. all in a pair of 4 are correct
|
||||
# NOTE: `items` is a tuple of (doc["group_id"], is_correct)
|
||||
preds_sort = sorted(items, key=lambda x: x[0])
|
||||
em_sums = [int(preds_sort[4*i][1]) + int(preds_sort[4*i+1][1]) + int(preds_sort[4*i+2][1]) + int(preds_sort[4*i+3][1]) for i in range(len(preds_sort) // 4)]
|
||||
em_sums = [
|
||||
int(preds_sort[4 * i][1])
|
||||
+ int(preds_sort[4 * i + 1][1])
|
||||
+ int(preds_sort[4 * i + 2][1])
|
||||
+ int(preds_sort[4 * i + 3][1])
|
||||
for i in range(len(preds_sort) // 4)
|
||||
]
|
||||
em_cors = [em_sums[i] == 4 for i in range(len(em_sums))]
|
||||
return mean(em_cors)
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean,
|
||||
'em': self.calc_em
|
||||
}
|
||||
return {"acc": mean, "em": self.calc_em}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True,
|
||||
'em': True
|
||||
}
|
||||
return {"acc": True, "em": True}
|
||||
|
||||
|
||||
class EthicsUtilitarianismOriginal(Ethics):
|
||||
@@ -236,14 +228,25 @@ class EthicsUtilitarianismOriginal(Ethics):
|
||||
|
||||
def fewshot_examples(self, k, rnd):
|
||||
# Overwriting fewshot examples as k can be max 5
|
||||
assert k <= 5, "There are only 5 possible shots for this task. Refer to the V2 for more."
|
||||
assert (
|
||||
k <= 5
|
||||
), "There are only 5 possible shots for this task. Refer to the V2 for more."
|
||||
# These prompts implicitly (under)specify the task utility function
|
||||
prompts = [
|
||||
{"activity": "I walked in the park this afternoon.", "rating": "7"},
|
||||
{"activity": "I walked in the parking lot this afternoon.", "rating": "5"},
|
||||
{"activity": "I stopped to eat at a fast food restaurant. The food was cold.", "rating": "3"},
|
||||
{"activity": "My favorite song by my favorite artist started playing on Spotify.", "rating": "8"},
|
||||
{"activity": "I tripped and fell down the stairs at school. Several classmates made fun of me for falling.", "rating": "2"},
|
||||
{
|
||||
"activity": "I stopped to eat at a fast food restaurant. The food was cold.",
|
||||
"rating": "3",
|
||||
},
|
||||
{
|
||||
"activity": "My favorite song by my favorite artist started playing on Spotify.",
|
||||
"rating": "8",
|
||||
},
|
||||
{
|
||||
"activity": "I tripped and fell down the stairs at school. Several classmates made fun of me for falling.",
|
||||
"rating": "2",
|
||||
},
|
||||
]
|
||||
return rnd.sample(prompts, k)
|
||||
|
||||
@@ -282,14 +285,10 @@ class EthicsUtilitarianismOriginal(Ethics):
|
||||
}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class EthicsUtilitarianism(Ethics):
|
||||
@@ -297,6 +296,7 @@ class EthicsUtilitarianism(Ethics):
|
||||
This is a variation of the original Utilitarianism task used in the paper, where the situations are directly compared.
|
||||
This allows scaling to >5 shots.
|
||||
"""
|
||||
|
||||
VERSION = 0
|
||||
DATASET_NAME = "utilitarianism"
|
||||
|
||||
@@ -339,19 +339,13 @@ class EthicsUtilitarianism(Ethics):
|
||||
ll_yes, ll_no = results
|
||||
pred = ll_yes > ll_no
|
||||
gold = doc["label"]
|
||||
return {
|
||||
"acc": pred == gold
|
||||
}
|
||||
return {"acc": pred == gold}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class EthicsVirtue(Ethics):
|
||||
@@ -362,9 +356,8 @@ class EthicsVirtue(Ethics):
|
||||
return doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Sentence: {}\nQuestion: Does the character in this sentence exhibit the trait \"{}\"?\nAnswer:".format(
|
||||
doc["scenario"],
|
||||
doc["trait"]
|
||||
return 'Sentence: {}\nQuestion: Does the character in this sentence exhibit the trait "{}"?\nAnswer:'.format(
|
||||
doc["scenario"], doc["trait"]
|
||||
)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
@@ -379,27 +372,25 @@ class EthicsVirtue(Ethics):
|
||||
ll_yes, ll_no = results
|
||||
pred = ll_yes > ll_no
|
||||
gold = bool(int(doc["label"]))
|
||||
return {
|
||||
"acc": pred == gold,
|
||||
"em": [doc["group_id"], pred == gold]
|
||||
}
|
||||
return {"acc": pred == gold, "em": [doc["group_id"], pred == gold]}
|
||||
|
||||
def calc_em(self, items):
|
||||
# Calculate exact matches - i.e. all in a pair of 5 are correct
|
||||
# NOTE: `items` is a tuple of (doc["group_id"], is_correct)
|
||||
preds_sort = sorted(items, key=lambda x: x[0])
|
||||
em_sums = [int(preds_sort[5*i][1]) + int(preds_sort[5*i+1][1]) + int(preds_sort[5*i+2][1]) + int(preds_sort[5*i+3][1]) + int(preds_sort[5*i+4][1]) for i in range(len(preds_sort) // 5)]
|
||||
em_sums = [
|
||||
int(preds_sort[5 * i][1])
|
||||
+ int(preds_sort[5 * i + 1][1])
|
||||
+ int(preds_sort[5 * i + 2][1])
|
||||
+ int(preds_sort[5 * i + 3][1])
|
||||
+ int(preds_sort[5 * i + 4][1])
|
||||
for i in range(len(preds_sort) // 5)
|
||||
]
|
||||
em_cors = [em_sums[i] == 5 for i in range(len(em_sums))]
|
||||
return mean(em_cors)
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean,
|
||||
'em': self.calc_em
|
||||
}
|
||||
return {"acc": mean, "em": self.calc_em}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True,
|
||||
'em': True
|
||||
}
|
||||
return {"acc": True, "em": True}
|
||||
|
||||
@@ -47,8 +47,7 @@ class Math(Task):
|
||||
return map(self._process_doc, self.dataset["test"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
doc["answer"] = self.remove_boxed(
|
||||
self.last_boxed_only_string(doc["solution"]))
|
||||
doc["answer"] = self.remove_boxed(self.last_boxed_only_string(doc["solution"]))
|
||||
return doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
@@ -72,23 +71,19 @@ class Math(Task):
|
||||
if len(indices) <= 1:
|
||||
answer = results[0]
|
||||
else:
|
||||
answer = results[0][indices[0]+1:indices[-1]]
|
||||
answer = results[0][indices[0] + 1 : indices[-1]]
|
||||
|
||||
if self.is_equiv(answer, self.remove_boxed(self.last_boxed_only_string(doc["solution"]))):
|
||||
if self.is_equiv(
|
||||
answer, self.remove_boxed(self.last_boxed_only_string(doc["solution"]))
|
||||
):
|
||||
retval = 1
|
||||
return {
|
||||
"acc": retval
|
||||
}
|
||||
return {"acc": retval}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'acc': mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'acc': True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def is_equiv(self, str1, str2, verbose=False):
|
||||
if str1 is None and str2 is None:
|
||||
@@ -109,18 +104,18 @@ class Math(Task):
|
||||
def remove_boxed(self, s):
|
||||
if "\\boxed " in s:
|
||||
left = "\\boxed "
|
||||
assert s[:len(left)] == left
|
||||
return s[len(left):]
|
||||
assert s[: len(left)] == left
|
||||
return s[len(left) :]
|
||||
|
||||
left = "\\boxed{"
|
||||
|
||||
assert s[:len(left)] == left
|
||||
assert s[: len(left)] == left
|
||||
assert s[-1] == "}"
|
||||
|
||||
return s[len(left):-1]
|
||||
return s[len(left) : -1]
|
||||
|
||||
def last_boxed_only_string(self, string):
|
||||
|
||||
|
||||
idx = string.rfind("\\boxed")
|
||||
if "\\boxed " in string:
|
||||
return "\\boxed " + string.split("\\boxed ")[-1].split("$")[0]
|
||||
@@ -145,7 +140,7 @@ class Math(Task):
|
||||
if right_brace_idx is None:
|
||||
retval = None
|
||||
else:
|
||||
retval = string[idx:right_brace_idx + 1]
|
||||
retval = string[idx : right_brace_idx + 1]
|
||||
|
||||
return retval
|
||||
|
||||
@@ -288,34 +283,34 @@ class Math(Task):
|
||||
|
||||
class MathAlgebra(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'algebra'
|
||||
DATASET_NAME = "algebra"
|
||||
|
||||
|
||||
class MathCountingAndProbability(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'counting_and_probability'
|
||||
DATASET_NAME = "counting_and_probability"
|
||||
|
||||
|
||||
class MathGeometry(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'geometry'
|
||||
DATASET_NAME = "geometry"
|
||||
|
||||
|
||||
class MathIntermediateAlgebra(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'intermediate_algebra'
|
||||
DATASET_NAME = "intermediate_algebra"
|
||||
|
||||
|
||||
class MathNumberTheory(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'number_theory'
|
||||
DATASET_NAME = "number_theory"
|
||||
|
||||
|
||||
class MathPrealgebra(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'prealgebra'
|
||||
DATASET_NAME = "prealgebra"
|
||||
|
||||
|
||||
class MathPrecalculus(Math):
|
||||
VERSION = 1
|
||||
DATASET_NAME = 'precalculus'
|
||||
DATASET_NAME = "precalculus"
|
||||
|
||||
@@ -3,11 +3,11 @@ Measuring Massive Multitask Language Understanding
|
||||
https://arxiv.org/pdf/2009.03300.pdf
|
||||
|
||||
The Hendryck's Test is a benchmark that measured a text model’s multitask accuracy.
|
||||
The test covers 57 tasks including elementary mathematics, US history, computer
|
||||
The test covers 57 tasks including elementary mathematics, US history, computer
|
||||
science, law, and more. To attain high accuracy on this test, models must possess
|
||||
extensive world knowledge and problem solving ability. By comprehensively evaluating
|
||||
the breadth and depth of a model’s academic and professional understanding,
|
||||
Hendryck's Test can be used to analyze models across many tasks and to identify
|
||||
the breadth and depth of a model’s academic and professional understanding,
|
||||
Hendryck's Test can be used to analyze models across many tasks and to identify
|
||||
important shortcomings.
|
||||
|
||||
Homepage: https://github.com/hendrycks/test
|
||||
@@ -25,16 +25,65 @@ _CITATION = """
|
||||
"""
|
||||
|
||||
|
||||
SUBJECTS = ['abstract_algebra', 'anatomy', 'astronomy', 'business_ethics', 'clinical_knowledge', 'college_biology',
|
||||
'college_chemistry', 'college_computer_science', 'college_mathematics', 'college_medicine', 'college_physics',
|
||||
'computer_security', 'conceptual_physics', 'econometrics', 'electrical_engineering', 'elementary_mathematics',
|
||||
'formal_logic', 'global_facts', 'high_school_biology', 'high_school_chemistry', 'high_school_computer_science',
|
||||
'high_school_european_history', 'high_school_geography', 'high_school_government_and_politics', 'high_school_macroeconomics',
|
||||
'high_school_mathematics', 'high_school_microeconomics', 'high_school_physics', 'high_school_psychology', 'high_school_statistics',
|
||||
'high_school_us_history', 'high_school_world_history', 'human_aging', 'human_sexuality', 'international_law', 'jurisprudence',
|
||||
'logical_fallacies', 'machine_learning', 'management', 'marketing', 'medical_genetics', 'miscellaneous', 'moral_disputes',
|
||||
'moral_scenarios', 'nutrition', 'philosophy', 'prehistory', 'professional_accounting', 'professional_law', 'professional_medicine',
|
||||
'professional_psychology', 'public_relations', 'security_studies', 'sociology', 'us_foreign_policy', 'virology', 'world_religions']
|
||||
SUBJECTS = [
|
||||
"abstract_algebra",
|
||||
"anatomy",
|
||||
"astronomy",
|
||||
"business_ethics",
|
||||
"clinical_knowledge",
|
||||
"college_biology",
|
||||
"college_chemistry",
|
||||
"college_computer_science",
|
||||
"college_mathematics",
|
||||
"college_medicine",
|
||||
"college_physics",
|
||||
"computer_security",
|
||||
"conceptual_physics",
|
||||
"econometrics",
|
||||
"electrical_engineering",
|
||||
"elementary_mathematics",
|
||||
"formal_logic",
|
||||
"global_facts",
|
||||
"high_school_biology",
|
||||
"high_school_chemistry",
|
||||
"high_school_computer_science",
|
||||
"high_school_european_history",
|
||||
"high_school_geography",
|
||||
"high_school_government_and_politics",
|
||||
"high_school_macroeconomics",
|
||||
"high_school_mathematics",
|
||||
"high_school_microeconomics",
|
||||
"high_school_physics",
|
||||
"high_school_psychology",
|
||||
"high_school_statistics",
|
||||
"high_school_us_history",
|
||||
"high_school_world_history",
|
||||
"human_aging",
|
||||
"human_sexuality",
|
||||
"international_law",
|
||||
"jurisprudence",
|
||||
"logical_fallacies",
|
||||
"machine_learning",
|
||||
"management",
|
||||
"marketing",
|
||||
"medical_genetics",
|
||||
"miscellaneous",
|
||||
"moral_disputes",
|
||||
"moral_scenarios",
|
||||
"nutrition",
|
||||
"philosophy",
|
||||
"prehistory",
|
||||
"professional_accounting",
|
||||
"professional_law",
|
||||
"professional_medicine",
|
||||
"professional_psychology",
|
||||
"public_relations",
|
||||
"security_studies",
|
||||
"sociology",
|
||||
"us_foreign_policy",
|
||||
"virology",
|
||||
"world_religions",
|
||||
]
|
||||
|
||||
|
||||
def create_all_tasks():
|
||||
@@ -42,15 +91,14 @@ def create_all_tasks():
|
||||
:return: {task_name: task}
|
||||
e.g. {hendrycksTest-abstract_algebra: Task, hendrycksTest-anatomy: Task}
|
||||
"""
|
||||
return {
|
||||
f"hendrycksTest-{sub}": create_task(sub) for sub in SUBJECTS
|
||||
}
|
||||
return {f"hendrycksTest-{sub}": create_task(sub) for sub in SUBJECTS}
|
||||
|
||||
|
||||
def create_task(subject):
|
||||
class HendrycksTest(GeneralHendrycksTest):
|
||||
def __init__(self):
|
||||
super().__init__(subject)
|
||||
|
||||
return HendrycksTest
|
||||
|
||||
|
||||
@@ -81,27 +129,32 @@ class GeneralHendrycksTest(MultipleChoiceTask):
|
||||
def _process_doc(self, doc):
|
||||
def format_example(doc, keys):
|
||||
"""
|
||||
Question: <prompt>
|
||||
Choices:
|
||||
A. <choice1>
|
||||
B. <choice2>
|
||||
C. <choice3>
|
||||
D. <choice4>
|
||||
Answer:
|
||||
Question: <prompt>
|
||||
Choices:
|
||||
A. <choice1>
|
||||
B. <choice2>
|
||||
C. <choice3>
|
||||
D. <choice4>
|
||||
Answer:
|
||||
"""
|
||||
prompt = "Question: " + doc["question"] + "\nChoices:\n"
|
||||
prompt += "".join([f"{key}. {choice}\n" for key, choice in zip(keys, doc["choices"])])
|
||||
prompt += "".join(
|
||||
[f"{key}. {choice}\n" for key, choice in zip(keys, doc["choices"])]
|
||||
)
|
||||
prompt += "Answer:"
|
||||
return prompt
|
||||
keys = ['A', 'B', 'C', 'D']
|
||||
|
||||
keys = ["A", "B", "C", "D"]
|
||||
return {
|
||||
"query": format_example(doc, keys),
|
||||
"choices": doc["choices"],
|
||||
"gold": keys.index(doc["answer"]) if isinstance(doc["answer"], str) else doc["answer"]
|
||||
"gold": keys.index(doc["answer"])
|
||||
if isinstance(doc["answer"], str)
|
||||
else doc["answer"],
|
||||
}
|
||||
|
||||
def fewshot_examples(self, k, rnd):
|
||||
# fewshot_examples is not just sampling from train_docs because dev is
|
||||
# fewshot_examples is not just sampling from train_docs because dev is
|
||||
# in the same distribution as val/test but auxiliary_train isn't
|
||||
|
||||
if self._fewshot_docs is None:
|
||||
|
||||
@@ -20,7 +20,7 @@ from lm_eval.metrics import mean, perplexity
|
||||
|
||||
_CITATION = """
|
||||
@misc{
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
title={The LAMBADA dataset},
|
||||
DOI={10.5281/zenodo.2630551},
|
||||
publisher={Zenodo},
|
||||
@@ -53,38 +53,29 @@ class LAMBADA(Task):
|
||||
pass
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc['text'].rsplit(' ', 1)[0]
|
||||
return doc["text"].rsplit(" ", 1)[0]
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['text']
|
||||
return doc["text"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + doc['text'].rsplit(' ', 1)[1]
|
||||
return " " + doc["text"].rsplit(" ", 1)[1]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ll, is_greedy = rf.loglikelihood(ctx, self.doc_to_target(doc))
|
||||
|
||||
return ll, is_greedy
|
||||
|
||||
|
||||
def process_results(self, doc, results):
|
||||
ll, is_greedy = results
|
||||
|
||||
return {
|
||||
'ppl': ll,
|
||||
'acc': int(is_greedy)
|
||||
}
|
||||
|
||||
return {"ppl": ll, "acc": int(is_greedy)}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
'ppl': perplexity,
|
||||
'acc': mean
|
||||
}
|
||||
return {"ppl": perplexity, "acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
'ppl': False,
|
||||
'acc': True
|
||||
}
|
||||
return {"ppl": False, "acc": True}
|
||||
|
||||
@@ -18,7 +18,7 @@ from lm_eval.tasks.lambada import LAMBADA
|
||||
|
||||
_CITATION = """
|
||||
@misc{
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
title={The LAMBADA dataset},
|
||||
DOI={10.5281/zenodo.2630551},
|
||||
publisher={Zenodo},
|
||||
@@ -32,13 +32,13 @@ class LAMBADA_cloze(LAMBADA):
|
||||
VERSION = 0
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc['text'].rsplit(' ', 1)[0] + " ____. ->"
|
||||
return doc["text"].rsplit(" ", 1)[0] + " ____. ->"
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['text']
|
||||
return doc["text"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + doc['text'].rsplit(' ', 1)[1]
|
||||
return " " + doc["text"].rsplit(" ", 1)[1]
|
||||
|
||||
@@ -18,7 +18,7 @@ from . import lambada
|
||||
|
||||
_CITATION = """
|
||||
@misc{
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Quan Ngoc and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
||||
title={The LAMBADA dataset},
|
||||
DOI={10.5281/zenodo.2630551},
|
||||
publisher={Zenodo},
|
||||
@@ -33,28 +33,32 @@ class MultilingualLAMBADA(lambada.LAMBADA):
|
||||
|
||||
|
||||
class MultilingualLAMBADAEN(MultilingualLAMBADA):
|
||||
DATASET_NAME = 'en'
|
||||
DATASET_NAME = "en"
|
||||
|
||||
|
||||
class MultilingualLAMBADAFR(MultilingualLAMBADA):
|
||||
DATASET_NAME = 'fr'
|
||||
DATASET_NAME = "fr"
|
||||
|
||||
|
||||
class MultilingualLAMBADADE(MultilingualLAMBADA):
|
||||
DATASET_NAME = 'de'
|
||||
DATASET_NAME = "de"
|
||||
|
||||
|
||||
class MultilingualLAMBADAIT(MultilingualLAMBADA):
|
||||
DATASET_NAME = 'it'
|
||||
DATASET_NAME = "it"
|
||||
|
||||
|
||||
class MultilingualLAMBADAES(MultilingualLAMBADA):
|
||||
DATASET_NAME = 'es'
|
||||
DATASET_NAME = "es"
|
||||
|
||||
|
||||
LANG_CLASSES = [MultilingualLAMBADAEN, MultilingualLAMBADAFR,
|
||||
MultilingualLAMBADADE, MultilingualLAMBADAIT,
|
||||
MultilingualLAMBADAES]
|
||||
LANG_CLASSES = [
|
||||
MultilingualLAMBADAEN,
|
||||
MultilingualLAMBADAFR,
|
||||
MultilingualLAMBADADE,
|
||||
MultilingualLAMBADAIT,
|
||||
MultilingualLAMBADAES,
|
||||
]
|
||||
|
||||
|
||||
def construct_tasks():
|
||||
|
||||
+13
-12
@@ -17,7 +17,7 @@ from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
_CITATION = """
|
||||
@misc{liu2020logiqa,
|
||||
title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning},
|
||||
title={LogiQA: A Challenge Dataset for Machine Reading Comprehension with Logical Reasoning},
|
||||
author={Jian Liu and Leyang Cui and Hanmeng Liu and Dandan Huang and Yile Wang and Yue Zhang},
|
||||
year={2020},
|
||||
eprint={2007.08124},
|
||||
@@ -55,14 +55,14 @@ class LogiQA(MultipleChoiceTask):
|
||||
def _process_doc(self, doc):
|
||||
def format_example(doc, choices):
|
||||
"""
|
||||
Passage: <passage>
|
||||
Question: <question>
|
||||
Choices:
|
||||
A. <choice1>
|
||||
B. <choice2>
|
||||
C. <choice3>
|
||||
D. <choice4>
|
||||
Answer:
|
||||
Passage: <passage>
|
||||
Question: <question>
|
||||
Choices:
|
||||
A. <choice1>
|
||||
B. <choice2>
|
||||
C. <choice3>
|
||||
D. <choice4>
|
||||
Answer:
|
||||
"""
|
||||
prompt = "Passage: " + doc["context"] + "\n"
|
||||
prompt += "Question: " + doc["question"] + "\nChoices:\n"
|
||||
@@ -70,12 +70,13 @@ class LogiQA(MultipleChoiceTask):
|
||||
prompt += f"{choice.upper()}. {option}\n"
|
||||
prompt += "Answer:"
|
||||
return prompt
|
||||
choices = ['a', 'b', 'c', 'd']
|
||||
|
||||
choices = ["a", "b", "c", "d"]
|
||||
return {
|
||||
"passage": doc["context"], # Used for decontamination
|
||||
"passage": doc["context"], # Used for decontamination
|
||||
"query": format_example(doc, choices),
|
||||
"choices": doc["options"],
|
||||
"gold": choices.index(doc["label"])
|
||||
"gold": choices.index(doc["label"]),
|
||||
}
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
|
||||
@@ -14,7 +14,7 @@ from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
_CITATION = """
|
||||
@misc{amini2019mathqa,
|
||||
title={MathQA: Towards Interpretable Math Word Problem Solving with Operation-Based Formalisms},
|
||||
title={MathQA: Towards Interpretable Math Word Problem Solving with Operation-Based Formalisms},
|
||||
author={Aida Amini and Saadia Gabriel and Peter Lin and Rik Koncel-Kedziorski and Yejin Choi and Hannaneh Hajishirzi},
|
||||
year={2019},
|
||||
eprint={1905.13319},
|
||||
@@ -50,11 +50,14 @@ class MathQA(MultipleChoiceTask):
|
||||
return map(self._process_doc, self.dataset["test"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
answer_idx = ['a', 'b', 'c', 'd', 'e'].index(doc['correct'])
|
||||
choices = [c[4:].rstrip(" ,") for c in re.findall(r"[abcd] \) .*?, |e \) .*?$", doc['options'])]
|
||||
answer_idx = ["a", "b", "c", "d", "e"].index(doc["correct"])
|
||||
choices = [
|
||||
c[4:].rstrip(" ,")
|
||||
for c in re.findall(r"[abcd] \) .*?, |e \) .*?$", doc["options"])
|
||||
]
|
||||
|
||||
out_doc = {
|
||||
"query": "Question: " + doc['Problem'] + "\nAnswer:",
|
||||
"query": "Question: " + doc["Problem"] + "\nAnswer:",
|
||||
"choices": choices,
|
||||
"gold": answer_idx,
|
||||
}
|
||||
|
||||
+17
-18
@@ -3,18 +3,18 @@
|
||||
A Study of Temporal Commonsense Understanding
|
||||
https://arxiv.org/pdf/1909.03065.pdf
|
||||
|
||||
MC-TACO is a dataset of 13k question-answer pairs that require temporal commonsense
|
||||
MC-TACO is a dataset of 13k question-answer pairs that require temporal commonsense
|
||||
comprehension. The dataset contains five temporal properties, (1) duration (how long
|
||||
an event takes), (2) temporal ordering (typical order of events), (3) typical time
|
||||
an event takes), (2) temporal ordering (typical order of events), (3) typical time
|
||||
(when an event occurs), (4) frequency (how often an event occurs), and (5) stationarity
|
||||
(whether a state is maintained for a very long time or indefinitely).
|
||||
|
||||
WARNING: Running this task with a `--limit` arg will give misleading results! The
|
||||
WARNING: Running this task with a `--limit` arg will give misleading results! The
|
||||
corresponding dataset is structured such that each multiple-choice-question gathered
|
||||
by the authors is split into question-option pairs, where each such pair gets
|
||||
by the authors is split into question-option pairs, where each such pair gets
|
||||
siloed into an individual document for plausibility testing. Because the harness
|
||||
shuffles these documents, setting `--limit` will likely "cut off" certain candidate
|
||||
answers. This is a problem because the task's metrics require an exhaustive evaluation
|
||||
answers. This is a problem because the task's metrics require an exhaustive evaluation
|
||||
of a question's options. See section 4 of the paper for details.
|
||||
|
||||
Homepage: https://leaderboard.allenai.org/mctaco/submissions/public
|
||||
@@ -55,20 +55,22 @@ class MCTACO(Task):
|
||||
return self.dataset["test"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return f"{doc['sentence']}\nQuestion: {doc['question']}\n"\
|
||||
return (
|
||||
f"{doc['sentence']}\nQuestion: {doc['question']}\n"
|
||||
f"Answer: {doc['answer']}\nPlausible:"
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['question'] + " " + doc['sentence']
|
||||
return doc["question"] + " " + doc["sentence"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + ["no", "yes"][doc['label']]
|
||||
return " " + ["no", "yes"][doc["label"]]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
@@ -93,18 +95,15 @@ class MCTACO(Task):
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
ll_no, ll_yes = results
|
||||
gold = doc['label']
|
||||
gold = doc["label"]
|
||||
pred = int(ll_yes > ll_no)
|
||||
question_id = self._question2id(doc)
|
||||
items = (gold, pred, question_id)
|
||||
return {
|
||||
"em": items,
|
||||
"f1": items
|
||||
}
|
||||
return {"em": items, "f1": items}
|
||||
|
||||
def _question2id(self, doc):
|
||||
""" Returns an identifier for the question in the given document. """
|
||||
return " ".join([doc['sentence'], doc['question']])
|
||||
"""Returns an identifier for the question in the given document."""
|
||||
return " ".join([doc["sentence"], doc["question"]])
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
@@ -132,7 +131,7 @@ def exact_match(items):
|
||||
|
||||
|
||||
def f1(items):
|
||||
""" See section 4 "Evaluation Metrics" in the paper about the F1 metric used. """
|
||||
"""See section 4 "Evaluation Metrics" in the paper about the F1 metric used."""
|
||||
results = list(zip(*items))
|
||||
# Group the positive ("yes" = 1) golds and predictions by question.
|
||||
gold_positives, pred_positives = defaultdict(list), defaultdict(list)
|
||||
@@ -146,5 +145,5 @@ def f1(items):
|
||||
p = tp / pp if pp > 0.0 else 1.0
|
||||
r = tp / gp if gp > 0.0 else 1.0
|
||||
if p + r > 0.0:
|
||||
f1.append(2. * (p * r) / (p + r))
|
||||
f1.append(2.0 * (p * r) / (p + r))
|
||||
return np.mean(f1)
|
||||
|
||||
+5
-17
@@ -29,7 +29,7 @@ class MuTualBase(Task):
|
||||
VERSION = 1
|
||||
DATASET_PATH = inspect.getfile(lm_eval.datasets.mutual.mutual)
|
||||
DATASET_NAME = None
|
||||
CHOICES = ['A', 'B', 'C', 'D']
|
||||
CHOICES = ["A", "B", "C", "D"]
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
@@ -88,26 +88,14 @@ class MuTualBase(Task):
|
||||
r4_1 = np.argmax(results) == gold # r4_1 = accuracy
|
||||
ranks = sorted(results, reverse=True)
|
||||
r4_2 = (ranks.index(results[gold]) == 1) + r4_1
|
||||
mrr = 1. / (ranks.index(results[gold]) + 1) # `+ 1` for index offset
|
||||
return {
|
||||
"r@1": r4_1,
|
||||
"r@2": r4_2,
|
||||
"mrr": mrr
|
||||
}
|
||||
mrr = 1.0 / (ranks.index(results[gold]) + 1) # `+ 1` for index offset
|
||||
return {"r@1": r4_1, "r@2": r4_2, "mrr": mrr}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"r@1": mean,
|
||||
"r@2": mean,
|
||||
"mrr": mean
|
||||
}
|
||||
return {"r@1": mean, "r@2": mean, "mrr": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"r@1": True,
|
||||
"r@2": True,
|
||||
"mrr": True
|
||||
}
|
||||
return {"r@1": True, "r@2": True, "mrr": True}
|
||||
|
||||
|
||||
class MuTual(MuTualBase):
|
||||
|
||||
+134
-126
@@ -1,126 +1,134 @@
|
||||
"""
|
||||
Natural Questions: a Benchmark for Question Answering Research
|
||||
https://storage.googleapis.com/pub-tools-public-publication-data/pdf/1f7b46b5378d757553d3e92ead36bda2e4254244.pdf
|
||||
|
||||
The Natural Questions (NQ) corpus is a question-answering dataset that contains
|
||||
questions from real users and requires QA systems to read and comprehend an entire
|
||||
Wikipedia article that may or may not contain the answer to the question. The
|
||||
inclusion of real user questions, and the requirement that solutions should read
|
||||
an entire page to find the answer, cause NQ to be a more realistic and challenging
|
||||
task than prior QA datasets.
|
||||
|
||||
TODO: NaturalQS has a *really* large train set that huggingface just automatically
|
||||
downloads even if you dont use it. we should try and only download the val set and
|
||||
not even bother with the train set.
|
||||
|
||||
Homepage: https://ai.google.com/research/NaturalQuestions
|
||||
"""
|
||||
from lm_eval.base import Task
|
||||
from itertools import islice
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{47761,
|
||||
title={Natural Questions: a Benchmark for Question Answering Research},
|
||||
author={Tom Kwiatkowski and Jennimaria Palomaki and Olivia Redfield and Michael Collins and Ankur Parikh and Chris Alberti and Danielle Epstein and Illia Polosukhin and Matthew Kelcey and Jacob Devlin and Kenton Lee and Kristina N. Toutanova and Llion Jones and Ming-Wei Chang and Andrew Dai and Jakob Uszkoreit and Quoc Le and Slav Petrov},
|
||||
year={2019},
|
||||
journal={Transactions of the Association of Computational Linguistics}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class NaturalQs(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "natural_questions"
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
# Cache training for faster few-shot.
|
||||
# Data is too large to fit in memory.
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(self.dataset["train"])
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def fewshot_examples(self, k, rnd):
|
||||
# Data is too large to fit in memory. We just sample from the first bit.
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(islice(self.training_docs(), 0, 100000))
|
||||
|
||||
return rnd.sample(self._training_docs, k)
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return 'Q: ' + doc['question']['text'] + '\n\n' + 'A:'
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['question']['text']
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
# There's a short answer and a long answer. Based on the paper, I'm using the long answer.
|
||||
short_answer = doc['annotations']['short_answers'][0]['text']
|
||||
long_answer_start = doc['annotations']['long_answer'][0]['start_token']
|
||||
long_answer_end = doc['annotations']['long_answer'][0]['end_token']
|
||||
long_answer_span = doc['document']['tokens']['token'][long_answer_start:long_answer_end]
|
||||
long_answer_is_html = doc['document']['tokens']['is_html'][long_answer_start:long_answer_end]
|
||||
long_answer_chars = [tok for (tok, is_html) in zip(long_answer_span, long_answer_is_html) if not is_html]
|
||||
long_answer = " ".join(long_answer_chars)
|
||||
return long_answer # Replace with short_answer[0] for short answer
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
"""
|
||||
Natural Questions: a Benchmark for Question Answering Research
|
||||
https://storage.googleapis.com/pub-tools-public-publication-data/pdf/1f7b46b5378d757553d3e92ead36bda2e4254244.pdf
|
||||
|
||||
The Natural Questions (NQ) corpus is a question-answering dataset that contains
|
||||
questions from real users and requires QA systems to read and comprehend an entire
|
||||
Wikipedia article that may or may not contain the answer to the question. The
|
||||
inclusion of real user questions, and the requirement that solutions should read
|
||||
an entire page to find the answer, cause NQ to be a more realistic and challenging
|
||||
task than prior QA datasets.
|
||||
|
||||
TODO: NaturalQS has a *really* large train set that huggingface just automatically
|
||||
downloads even if you dont use it. we should try and only download the val set and
|
||||
not even bother with the train set.
|
||||
|
||||
Homepage: https://ai.google.com/research/NaturalQuestions
|
||||
"""
|
||||
from lm_eval.base import Task
|
||||
from itertools import islice
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{47761,
|
||||
title={Natural Questions: a Benchmark for Question Answering Research},
|
||||
author={Tom Kwiatkowski and Jennimaria Palomaki and Olivia Redfield and Michael Collins and Ankur Parikh and Chris Alberti and Danielle Epstein and Illia Polosukhin and Matthew Kelcey and Jacob Devlin and Kenton Lee and Kristina N. Toutanova and Llion Jones and Ming-Wei Chang and Andrew Dai and Jakob Uszkoreit and Quoc Le and Slav Petrov},
|
||||
year={2019},
|
||||
journal={Transactions of the Association of Computational Linguistics}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class NaturalQs(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "natural_questions"
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
# Cache training for faster few-shot.
|
||||
# Data is too large to fit in memory.
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(self.dataset["train"])
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def fewshot_examples(self, k, rnd):
|
||||
# Data is too large to fit in memory. We just sample from the first bit.
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(islice(self.training_docs(), 0, 100000))
|
||||
|
||||
return rnd.sample(self._training_docs, k)
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Q: " + doc["question"]["text"] + "\n\n" + "A:"
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["question"]["text"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
# There's a short answer and a long answer. Based on the paper, I'm using the long answer.
|
||||
short_answer = doc["annotations"]["short_answers"][0]["text"]
|
||||
long_answer_start = doc["annotations"]["long_answer"][0]["start_token"]
|
||||
long_answer_end = doc["annotations"]["long_answer"][0]["end_token"]
|
||||
long_answer_span = doc["document"]["tokens"]["token"][
|
||||
long_answer_start:long_answer_end
|
||||
]
|
||||
long_answer_is_html = doc["document"]["tokens"]["is_html"][
|
||||
long_answer_start:long_answer_end
|
||||
]
|
||||
long_answer_chars = [
|
||||
tok
|
||||
for (tok, is_html) in zip(long_answer_span, long_answer_is_html)
|
||||
if not is_html
|
||||
]
|
||||
long_answer = " ".join(long_answer_chars)
|
||||
return long_answer # Replace with short_answer[0] for short answer
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
+71
-71
@@ -1,71 +1,71 @@
|
||||
"""
|
||||
Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering
|
||||
https://arxiv.org/pdf/1809.02789.pdf
|
||||
|
||||
OpenBookQA is a question-answering dataset modeled after open book exams for
|
||||
assessing human understanding of a subject. It consists of 5,957 multiple-choice
|
||||
elementary-level science questions (4,957 train, 500 dev, 500 test), which probe
|
||||
the understanding of a small “book” of 1,326 core science facts and the application
|
||||
of these facts to novel situations. For training, the dataset includes a mapping
|
||||
from each question to the core science fact it was designed to probe. Answering
|
||||
OpenBookQA questions requires additional broad common knowledge, not contained
|
||||
in the book. The questions, by design, are answered incorrectly by both a retrieval-
|
||||
based algorithm and a word co-occurrence algorithm.
|
||||
|
||||
Homepage: https://allenai.org/data/open-book-qa
|
||||
"""
|
||||
from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@inproceedings{OpenBookQA2018,
|
||||
title={Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering},
|
||||
author={Todor Mihaylov and Peter Clark and Tushar Khot and Ashish Sabharwal},
|
||||
booktitle={EMNLP},
|
||||
year={2018}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class OpenBookQA(MultipleChoiceTask):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "openbookqa"
|
||||
DATASET_NAME = "main"
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return True
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def test_docs(self):
|
||||
return map(self._process_doc, self.dataset["test"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
out_doc = {
|
||||
"id": doc["id"],
|
||||
"query": doc["question_stem"],
|
||||
"choices": doc["choices"]["text"],
|
||||
"gold": ["A", "B", "C", "D"].index(doc["answerKey"].strip()),
|
||||
}
|
||||
return out_doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["query"]
|
||||
"""
|
||||
Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering
|
||||
https://arxiv.org/pdf/1809.02789.pdf
|
||||
|
||||
OpenBookQA is a question-answering dataset modeled after open book exams for
|
||||
assessing human understanding of a subject. It consists of 5,957 multiple-choice
|
||||
elementary-level science questions (4,957 train, 500 dev, 500 test), which probe
|
||||
the understanding of a small “book” of 1,326 core science facts and the application
|
||||
of these facts to novel situations. For training, the dataset includes a mapping
|
||||
from each question to the core science fact it was designed to probe. Answering
|
||||
OpenBookQA questions requires additional broad common knowledge, not contained
|
||||
in the book. The questions, by design, are answered incorrectly by both a retrieval-
|
||||
based algorithm and a word co-occurrence algorithm.
|
||||
|
||||
Homepage: https://allenai.org/data/open-book-qa
|
||||
"""
|
||||
from lm_eval.base import MultipleChoiceTask
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@inproceedings{OpenBookQA2018,
|
||||
title={Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering},
|
||||
author={Todor Mihaylov and Peter Clark and Tushar Khot and Ashish Sabharwal},
|
||||
booktitle={EMNLP},
|
||||
year={2018}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class OpenBookQA(MultipleChoiceTask):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "openbookqa"
|
||||
DATASET_NAME = "main"
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return True
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def test_docs(self):
|
||||
return map(self._process_doc, self.dataset["test"])
|
||||
|
||||
def _process_doc(self, doc):
|
||||
out_doc = {
|
||||
"id": doc["id"],
|
||||
"query": doc["question_stem"],
|
||||
"choices": doc["choices"]["text"],
|
||||
"gold": ["A", "B", "C", "D"].index(doc["answerKey"].strip()),
|
||||
}
|
||||
return out_doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["query"]
|
||||
|
||||
@@ -5,7 +5,7 @@ https://arxiv.org/pdf/1911.11641.pdf
|
||||
Physical Interaction: Question Answering (PIQA) is a physical commonsense
|
||||
reasoning and a corresponding benchmark dataset. PIQA was designed to investigate
|
||||
the physical knowledge of existing models. To what extent are current approaches
|
||||
actually learning about the world?
|
||||
actually learning about the world?
|
||||
|
||||
Homepage: https://yonatanbisk.com/piqa/
|
||||
"""
|
||||
|
||||
@@ -52,20 +52,21 @@ class PROST(MultipleChoiceTask):
|
||||
def test_docs(self):
|
||||
return map(self._process_doc, self.dataset["test"])
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
assert num_fewshot == 0, 'PROST is designed to probe models in a zero-shot fashion only.'
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert (
|
||||
num_fewshot == 0
|
||||
), "PROST is designed to probe models in a zero-shot fashion only."
|
||||
return super().fewshot_context(
|
||||
doc=doc,
|
||||
num_fewshot=num_fewshot,
|
||||
rnd=rnd,
|
||||
description=description
|
||||
doc=doc, num_fewshot=num_fewshot, rnd=rnd, description=description
|
||||
)
|
||||
|
||||
def _process_doc(self, doc):
|
||||
out_doc = {
|
||||
"query": f"{doc['context']}\nQuestion: {doc['ex_question']}\nAnswer:",
|
||||
"choices": [doc['A'], doc['B'], doc['C'], doc['D']],
|
||||
"gold": doc['label'],
|
||||
"choices": [doc["A"], doc["B"], doc["C"], doc["D"]],
|
||||
"gold": doc["label"],
|
||||
}
|
||||
return out_doc
|
||||
|
||||
|
||||
+10
-16
@@ -3,14 +3,14 @@ PubMedQA: A Dataset for Biomedical Research Question Answering
|
||||
https://arxiv.org/pdf/1909.06146.pdf
|
||||
|
||||
PubMedQA is a novel biomedical question answering (QA) dataset collected from
|
||||
PubMed abstracts. The task of PubMedQA is to answer research questions with
|
||||
yes/no/maybe (e.g.: Do preoperative statins reduce atrial fibrillation after
|
||||
coronary artery bypass grafting?) using the corresponding abstracts. PubMedQA
|
||||
has 1k expert-annotated, 61.2k unlabeled and 211.3k artificially generated QA
|
||||
PubMed abstracts. The task of PubMedQA is to answer research questions with
|
||||
yes/no/maybe (e.g.: Do preoperative statins reduce atrial fibrillation after
|
||||
coronary artery bypass grafting?) using the corresponding abstracts. PubMedQA
|
||||
has 1k expert-annotated, 61.2k unlabeled and 211.3k artificially generated QA
|
||||
instances. Each PubMedQA instance is composed of (1) a question which is either
|
||||
an existing research article title or derived from one, (2) a context which is
|
||||
the corresponding abstract without its conclusion, (3) a long answer, which is
|
||||
the conclusion of the abstract and, presumably, answers the research question,
|
||||
the conclusion of the abstract and, presumably, answers the research question,
|
||||
and (4) a yes/no/maybe answer which summarizes the conclusion.
|
||||
|
||||
Homepage: https://pubmedqa.github.io/
|
||||
@@ -53,9 +53,7 @@ class Pubmed_QA(Task):
|
||||
def doc_to_text(self, doc):
|
||||
ctxs = "\n".join(doc["context"]["contexts"])
|
||||
return "Abstract: {}\nQuestion: {}\nAnswer:".format(
|
||||
ctxs,
|
||||
doc["question"],
|
||||
doc["final_decision"]
|
||||
ctxs, doc["question"], doc["final_decision"]
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
@@ -68,7 +66,7 @@ class Pubmed_QA(Task):
|
||||
return " {}".format(doc["final_decision"])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns
|
||||
"""Uses RequestFactory to construct Requests and returns
|
||||
an iterable of Requests which will be sent to the LM.
|
||||
"""
|
||||
ll_yes, _ = rf.loglikelihood(ctx, " yes")
|
||||
@@ -81,15 +79,11 @@ class Pubmed_QA(Task):
|
||||
ll_yes, ll_no, ll_maybe = results
|
||||
pred = np.argmax(results)
|
||||
return {
|
||||
"acc": ["yes", "no", "maybe"][pred] == gold,
|
||||
"acc": ["yes", "no", "maybe"][pred] == gold,
|
||||
}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc" : mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc" : True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
@@ -3,9 +3,9 @@ QA4MRE 2011-2013: Overview of Question Answering for Machine Reading Evaluation
|
||||
https://www.cs.cmu.edu/~./hovy/papers/13CLEF-QA4MRE.pdf
|
||||
|
||||
The (English only) QA4MRE challenge which was run as a Lab at CLEF 2011-2013.
|
||||
The main objective of this exercise is to develop a methodology for evaluating
|
||||
Machine Reading systems through Question Answering and Reading Comprehension
|
||||
Tests. Systems should be able to extract knowledge from large volumes of text
|
||||
The main objective of this exercise is to develop a methodology for evaluating
|
||||
Machine Reading systems through Question Answering and Reading Comprehension
|
||||
Tests. Systems should be able to extract knowledge from large volumes of text
|
||||
and use this knowledge to answer questions. Four different tasks have been
|
||||
organized during these years: Main Task, Processing Modality and Negation for
|
||||
Machine Reading, Machine Reading of Biomedical Texts about Alzheimer's disease,
|
||||
@@ -47,7 +47,7 @@ class QA4MRE(MultipleChoiceTask):
|
||||
def _process_doc(self, doc):
|
||||
choices = doc["answer_options"]["answer_str"]
|
||||
out_doc = {
|
||||
"source": doc["document_str"].strip().replace("\'", "'"),
|
||||
"source": doc["document_str"].strip().replace("'", "'"),
|
||||
"query": doc["question_str"],
|
||||
"choices": choices,
|
||||
"gold": int(doc["correct_answer_id"]) - 1,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""
|
||||
"""
|
||||
A Dataset of Information-Seeking Questions and Answers Anchored in Research Papers
|
||||
https://arxiv.org/abs/2105.03011
|
||||
|
||||
|
||||
+123
-112
@@ -1,112 +1,123 @@
|
||||
"""
|
||||
QuAC: Question Answering in Context
|
||||
https://arxiv.org/abs/1808.07036
|
||||
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
participating in information seeking dialog. Data instances consist of an interactive
|
||||
dialog between two crowd workers: (1) a student who poses a sequence of freeform
|
||||
questions to learn as much as possible about a hidden Wikipedia text, and (2)
|
||||
a teacher who answers the questions by providing short excerpts (spans) from the text.
|
||||
|
||||
Homepage: https://quac.ai/
|
||||
"""
|
||||
import inspect
|
||||
import lm_eval.datasets.quac.quac
|
||||
from lm_eval.base import Task
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{choi2018quac,
|
||||
title={Quac: Question answering in context},
|
||||
author={Choi, Eunsol and He, He and Iyyer, Mohit and Yatskar, Mark and Yih, Wen-tau and Choi, Yejin and Liang, Percy and Zettlemoyer, Luke},
|
||||
journal={arXiv preprint arXiv:1808.07036},
|
||||
year={2018}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class QuAC(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = inspect.getfile(lm_eval.datasets.quac.quac)
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def test_docs(self):
|
||||
raise NotImplementedError("QuAC has no test docs.")
|
||||
|
||||
def _process_doc(self, doc):
|
||||
doc["title"] = doc['title'] + ' - ' + doc['section_title']
|
||||
return doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return 'TITLE: ' + doc['title'] + '\n' + 'PARAGRAPH: ' + doc['paragraph'] + '\n\n' + 'Q: ' + doc['question'] + '\n\n' + 'A: '
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['paragraph']
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return doc['answer']
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError('Evaluation not implemented')
|
||||
"""
|
||||
QuAC: Question Answering in Context
|
||||
https://arxiv.org/abs/1808.07036
|
||||
|
||||
Question Answering in Context (QuAC) is a dataset for modeling, understanding, and
|
||||
participating in information seeking dialog. Data instances consist of an interactive
|
||||
dialog between two crowd workers: (1) a student who poses a sequence of freeform
|
||||
questions to learn as much as possible about a hidden Wikipedia text, and (2)
|
||||
a teacher who answers the questions by providing short excerpts (spans) from the text.
|
||||
|
||||
Homepage: https://quac.ai/
|
||||
"""
|
||||
import inspect
|
||||
import lm_eval.datasets.quac.quac
|
||||
from lm_eval.base import Task
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{choi2018quac,
|
||||
title={Quac: Question answering in context},
|
||||
author={Choi, Eunsol and He, He and Iyyer, Mohit and Yatskar, Mark and Yih, Wen-tau and Choi, Yejin and Liang, Percy and Zettlemoyer, Luke},
|
||||
journal={arXiv preprint arXiv:1808.07036},
|
||||
year={2018}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class QuAC(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = inspect.getfile(lm_eval.datasets.quac.quac)
|
||||
DATASET_NAME = None
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(map(self._process_doc, self.dataset["train"]))
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return map(self._process_doc, self.dataset["validation"])
|
||||
|
||||
def test_docs(self):
|
||||
raise NotImplementedError("QuAC has no test docs.")
|
||||
|
||||
def _process_doc(self, doc):
|
||||
doc["title"] = doc["title"] + " - " + doc["section_title"]
|
||||
return doc
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return (
|
||||
"TITLE: "
|
||||
+ doc["title"]
|
||||
+ "\n"
|
||||
+ "PARAGRAPH: "
|
||||
+ doc["paragraph"]
|
||||
+ "\n\n"
|
||||
+ "Q: "
|
||||
+ doc["question"]
|
||||
+ "\n\n"
|
||||
+ "A: "
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["paragraph"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return doc["answer"]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
# TODO: implement evaluation.
|
||||
raise NotImplementedError("Evaluation not implemented")
|
||||
|
||||
+48
-43
@@ -20,7 +20,7 @@ _CITATION = """
|
||||
@article{lai2017large,
|
||||
title={RACE: Large-scale ReAding Comprehension Dataset From Examinations},
|
||||
author={Lai, Guokun and Xie, Qizhe and Liu, Hanxiao and Yang, Yiming and Hovy, Eduard},
|
||||
journal={arXiv preprint arXiv:1704.04683},
|
||||
journal={arXiv preprint arXiv:1704.04683},
|
||||
year={2017}
|
||||
}
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ class RACE(Task):
|
||||
DATASET_NAME = "high"
|
||||
|
||||
cache = {}
|
||||
letter_to_num = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
|
||||
letter_to_num = {"A": 0, "B": 1, "C": 2, "D": 3}
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
@@ -59,17 +59,27 @@ class RACE(Task):
|
||||
# is shown that one document is made per passage.
|
||||
|
||||
r = collections.defaultdict(list)
|
||||
for item in datasets.load_dataset(path=self.DATASET_PATH, name=self.DATASET_NAME)[set]:
|
||||
r[item['article']].append(item)
|
||||
|
||||
res = list(r.values() >> each(lambda x: {
|
||||
'article': x[0]['article'],
|
||||
'problems': x >> each(lambda y: {
|
||||
'question': y['question'],
|
||||
'answer': y['answer'],
|
||||
'options': y['options'],
|
||||
})
|
||||
}))
|
||||
for item in datasets.load_dataset(
|
||||
path=self.DATASET_PATH, name=self.DATASET_NAME
|
||||
)[set]:
|
||||
r[item["article"]].append(item)
|
||||
|
||||
res = list(
|
||||
r.values()
|
||||
>> each(
|
||||
lambda x: {
|
||||
"article": x[0]["article"],
|
||||
"problems": x
|
||||
>> each(
|
||||
lambda y: {
|
||||
"question": y["question"],
|
||||
"answer": y["answer"],
|
||||
"options": y["options"],
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
self.cache[set] = res
|
||||
return res
|
||||
@@ -85,55 +95,56 @@ class RACE(Task):
|
||||
|
||||
@classmethod
|
||||
def get_answer_option(cls, problem):
|
||||
answer = cls.letter_to_num[problem['answer']]
|
||||
return problem['options'][answer]
|
||||
answer = cls.letter_to_num[problem["answer"]]
|
||||
return problem["options"][answer]
|
||||
|
||||
@classmethod
|
||||
def last_problem(cls, doc):
|
||||
return doc['problems'][-1]
|
||||
return doc["problems"][-1]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
text = 'Article: ' + doc['article'] + '\n\n'
|
||||
for problem in doc['problems'][:-1]:
|
||||
if problem['question'][-6:] == ' _ .':
|
||||
text += problem['question'][-5:] + self.get_answer_option(problem) + '\n'
|
||||
text = "Article: " + doc["article"] + "\n\n"
|
||||
for problem in doc["problems"][:-1]:
|
||||
if problem["question"][-6:] == " _ .":
|
||||
text += (
|
||||
problem["question"][-5:] + self.get_answer_option(problem) + "\n"
|
||||
)
|
||||
else:
|
||||
question = 'Question: ' + problem['question'] + '\n'
|
||||
answer = 'Answer: ' + self.get_answer_option(problem) + '\n'
|
||||
question = "Question: " + problem["question"] + "\n"
|
||||
answer = "Answer: " + self.get_answer_option(problem) + "\n"
|
||||
text += question + answer
|
||||
text += self.last_problem(doc)['question']
|
||||
text += self.last_problem(doc)["question"]
|
||||
return text
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['article']
|
||||
return doc["article"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + self.get_answer_option(self.last_problem(doc))
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
problem = self.last_problem(doc)
|
||||
ll_choices = [
|
||||
rf.loglikelihood(ctx, " " + problem['options'][i])[0]
|
||||
for i in range(4)
|
||||
rf.loglikelihood(ctx, " " + problem["options"][i])[0] for i in range(4)
|
||||
]
|
||||
return ll_choices
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
@@ -141,28 +152,22 @@ class RACE(Task):
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
gold = self.letter_to_num[self.last_problem(doc)['answer']]
|
||||
gold = self.letter_to_num[self.last_problem(doc)["answer"]]
|
||||
pred = np.argmax(results)
|
||||
return {
|
||||
"acc": int(pred == gold)
|
||||
}
|
||||
return {"acc": int(pred == gold)}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
@@ -59,14 +59,16 @@ class SATAnalogies(MultipleChoiceTask):
|
||||
|
||||
def _process_doc(self, doc):
|
||||
return {
|
||||
'source': doc['source'],
|
||||
'query': doc['stem'].split(' ')[:2],
|
||||
'choices': ["{} is to {}".format(*c.split(' ')[:2]) for c in doc["choices"]],
|
||||
'gold': ['a', 'b', 'c', 'd', 'e'].index(doc['solution'].strip()),
|
||||
"source": doc["source"],
|
||||
"query": doc["stem"].split(" ")[:2],
|
||||
"choices": [
|
||||
"{} is to {}".format(*c.split(" ")[:2]) for c in doc["choices"]
|
||||
],
|
||||
"gold": ["a", "b", "c", "d", "e"].index(doc["solution"].strip()),
|
||||
}
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "{} is to {} as".format(*doc['query'])
|
||||
return "{} is to {} as".format(*doc["query"])
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
@@ -54,10 +54,10 @@ class SciQ(MultipleChoiceTask):
|
||||
doc["distractor3"],
|
||||
doc["correct_answer"],
|
||||
]
|
||||
src = doc['support']
|
||||
src = doc["support"]
|
||||
out_doc = {
|
||||
"source": src,
|
||||
"query": doc['question'],
|
||||
"query": doc["question"],
|
||||
"choices": choices,
|
||||
"gold": 3,
|
||||
}
|
||||
|
||||
+219
-169
@@ -1,169 +1,219 @@
|
||||
"""
|
||||
Know What You Don’t Know: Unanswerable Questions for SQuAD
|
||||
https://arxiv.org/pdf/1806.03822.pdf
|
||||
|
||||
Stanford Question Answering Dataset (SQuAD) is a reading comprehension dataset,
|
||||
consisting of questions posed by crowdworkers on a set of Wikipedia articles,
|
||||
where the answer to every question is a segment of text, or span, from the
|
||||
corresponding reading passage, or the question might be unanswerable.
|
||||
SQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable
|
||||
questions written adversarially by crowdworkers to look similar to answerable ones.
|
||||
To do well on SQuAD2.0, systems must not only answer questions when possible, but
|
||||
also determine when no answer is supported by the paragraph and abstain from answering.
|
||||
|
||||
Homepage: https://rajpurkar.github.io/SQuAD-explorer/
|
||||
"""
|
||||
import datasets
|
||||
from math import exp
|
||||
from lm_eval.base import rf, Task
|
||||
from functools import partial
|
||||
from packaging import version
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@misc{rajpurkar2018know,
|
||||
title={Know What You Don't Know: Unanswerable Questions for SQuAD},
|
||||
author={Pranav Rajpurkar and Robin Jia and Percy Liang},
|
||||
year={2018},
|
||||
eprint={1806.03822},
|
||||
archivePrefix={arXiv},
|
||||
primaryClass={cs.CL}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def _squad_metric(predictions, references):
|
||||
squad_metric = datasets.load_metric("squad_v2")
|
||||
return squad_metric.compute(predictions=predictions, references=references)
|
||||
|
||||
|
||||
def _squad_agg(key, items):
|
||||
predictions, references = zip(*items)
|
||||
|
||||
return _squad_metric(predictions=predictions, references=references)[key]
|
||||
|
||||
|
||||
class SQuAD2(Task):
|
||||
VERSION = 1
|
||||
DATASET_PATH = "squad_v2"
|
||||
DATASET_NAME = None
|
||||
|
||||
# HF changed squad on us so we have to make sure we aren't running the old one
|
||||
assert version.parse(datasets.__version__) >= version.parse("1.11.0"), "datasets v1.11.0 or later required for SQuAD"
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
return self.dataset["train"]
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return 'Title: ' + doc['title'] + '\n\n' + 'Background: ' + doc['context'] + '\n\n' + 'Question: ' + doc['question'] + '\n\n' + 'Answer:'
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['context']
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
answer_list = doc['answers']['text']
|
||||
if len(answer_list) > 0:
|
||||
answer = answer_list[0]
|
||||
else:
|
||||
answer = 'unanswerable'
|
||||
return " " + answer
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
continuation = rf.greedy_until(ctx, ['\n'])
|
||||
is_unanswerable = rf.loglikelihood(ctx, " " + "unanswerable")
|
||||
return continuation, is_unanswerable
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
continuation, (logprob_unanswerable, _) = results
|
||||
|
||||
no_answer_probability = exp(logprob_unanswerable)
|
||||
|
||||
predictions = {
|
||||
'id': doc['id'],
|
||||
'prediction_text': continuation,
|
||||
'no_answer_probability': no_answer_probability,
|
||||
}
|
||||
|
||||
references = {
|
||||
'id': doc['id'],
|
||||
'answers': doc['answers'],
|
||||
}
|
||||
|
||||
return {
|
||||
'exact': (predictions, references), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'f1': (predictions, references), # The F-score of predicted tokens versus the gold answer
|
||||
'HasAns_exact': (predictions, references), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'HasAns_f1': (predictions, references), # The F-score of predicted tokens versus the gold answer
|
||||
'NoAns_exact': (predictions, references), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'NoAns_f1': (predictions, references), # The F-score of predicted tokens versus the gold answer
|
||||
'best_exact': (predictions, references), # Best exact match (with varying threshold)
|
||||
'best_f1': (predictions, references), # Best F1 (with varying threshold)
|
||||
}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
'exact': partial(_squad_agg, 'exact'), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'f1': partial(_squad_agg, 'f1'), # The F-score of predicted tokens versus the gold answer
|
||||
'HasAns_exact': partial(_squad_agg, 'HasAns_exact'), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'HasAns_f1': partial(_squad_agg, 'HasAns_f1'), # The F-score of predicted tokens versus the gold answer
|
||||
'NoAns_exact': partial(_squad_agg, 'NoAns_exact'), # Exact match (the normalized answer exactly match the gold answer)
|
||||
'NoAns_f1': partial(_squad_agg, 'NoAns_f1'), # The F-score of predicted tokens versus the gold answer
|
||||
'best_exact': partial(_squad_agg, 'best_exact'), # Best exact match (with varying threshold)
|
||||
'best_f1': partial(_squad_agg, 'best_f1'), # Best F1 (with varying threshold)
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
'exact': True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
'f1': True, # The F-score of predicted tokens versus the gold answer
|
||||
'HasAns_exact': True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
'HasAns_f1': True, # The F-score of predicted tokens versus the gold answer
|
||||
'NoAns_exact': True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
'NoAns_f1': True, # The F-score of predicted tokens versus the gold answer
|
||||
'best_exact': True, # Best exact match (with varying threshold)
|
||||
'best_f1': True, # Best F1 (with varying threshold)
|
||||
}
|
||||
"""
|
||||
Know What You Don’t Know: Unanswerable Questions for SQuAD
|
||||
https://arxiv.org/pdf/1806.03822.pdf
|
||||
|
||||
Stanford Question Answering Dataset (SQuAD) is a reading comprehension dataset,
|
||||
consisting of questions posed by crowdworkers on a set of Wikipedia articles,
|
||||
where the answer to every question is a segment of text, or span, from the
|
||||
corresponding reading passage, or the question might be unanswerable.
|
||||
SQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable
|
||||
questions written adversarially by crowdworkers to look similar to answerable ones.
|
||||
To do well on SQuAD2.0, systems must not only answer questions when possible, but
|
||||
also determine when no answer is supported by the paragraph and abstain from answering.
|
||||
|
||||
Homepage: https://rajpurkar.github.io/SQuAD-explorer/
|
||||
"""
|
||||
import datasets
|
||||
from math import exp
|
||||
from lm_eval.base import rf, Task
|
||||
from functools import partial
|
||||
from packaging import version
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@misc{rajpurkar2018know,
|
||||
title={Know What You Don't Know: Unanswerable Questions for SQuAD},
|
||||
author={Pranav Rajpurkar and Robin Jia and Percy Liang},
|
||||
year={2018},
|
||||
eprint={1806.03822},
|
||||
archivePrefix={arXiv},
|
||||
primaryClass={cs.CL}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def _squad_metric(predictions, references):
|
||||
squad_metric = datasets.load_metric("squad_v2")
|
||||
return squad_metric.compute(predictions=predictions, references=references)
|
||||
|
||||
|
||||
def _squad_agg(key, items):
|
||||
predictions, references = zip(*items)
|
||||
|
||||
return _squad_metric(predictions=predictions, references=references)[key]
|
||||
|
||||
|
||||
class SQuAD2(Task):
|
||||
VERSION = 1
|
||||
DATASET_PATH = "squad_v2"
|
||||
DATASET_NAME = None
|
||||
|
||||
# HF changed squad on us so we have to make sure we aren't running the old one
|
||||
assert version.parse(datasets.__version__) >= version.parse(
|
||||
"1.11.0"
|
||||
), "datasets v1.11.0 or later required for SQuAD"
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
return self.dataset["train"]
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return (
|
||||
"Title: "
|
||||
+ doc["title"]
|
||||
+ "\n\n"
|
||||
+ "Background: "
|
||||
+ doc["context"]
|
||||
+ "\n\n"
|
||||
+ "Question: "
|
||||
+ doc["question"]
|
||||
+ "\n\n"
|
||||
+ "Answer:"
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["context"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
answer_list = doc["answers"]["text"]
|
||||
if len(answer_list) > 0:
|
||||
answer = answer_list[0]
|
||||
else:
|
||||
answer = "unanswerable"
|
||||
return " " + answer
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
continuation = rf.greedy_until(ctx, ["\n"])
|
||||
is_unanswerable = rf.loglikelihood(ctx, " " + "unanswerable")
|
||||
return continuation, is_unanswerable
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
continuation, (logprob_unanswerable, _) = results
|
||||
|
||||
no_answer_probability = exp(logprob_unanswerable)
|
||||
|
||||
predictions = {
|
||||
"id": doc["id"],
|
||||
"prediction_text": continuation,
|
||||
"no_answer_probability": no_answer_probability,
|
||||
}
|
||||
|
||||
references = {
|
||||
"id": doc["id"],
|
||||
"answers": doc["answers"],
|
||||
}
|
||||
|
||||
return {
|
||||
"exact": (
|
||||
predictions,
|
||||
references,
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"f1": (
|
||||
predictions,
|
||||
references,
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"HasAns_exact": (
|
||||
predictions,
|
||||
references,
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"HasAns_f1": (
|
||||
predictions,
|
||||
references,
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"NoAns_exact": (
|
||||
predictions,
|
||||
references,
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"NoAns_f1": (
|
||||
predictions,
|
||||
references,
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"best_exact": (
|
||||
predictions,
|
||||
references,
|
||||
), # Best exact match (with varying threshold)
|
||||
"best_f1": (predictions, references), # Best F1 (with varying threshold)
|
||||
}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"exact": partial(
|
||||
_squad_agg, "exact"
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"f1": partial(
|
||||
_squad_agg, "f1"
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"HasAns_exact": partial(
|
||||
_squad_agg, "HasAns_exact"
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"HasAns_f1": partial(
|
||||
_squad_agg, "HasAns_f1"
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"NoAns_exact": partial(
|
||||
_squad_agg, "NoAns_exact"
|
||||
), # Exact match (the normalized answer exactly match the gold answer)
|
||||
"NoAns_f1": partial(
|
||||
_squad_agg, "NoAns_f1"
|
||||
), # The F-score of predicted tokens versus the gold answer
|
||||
"best_exact": partial(
|
||||
_squad_agg, "best_exact"
|
||||
), # Best exact match (with varying threshold)
|
||||
"best_f1": partial(
|
||||
_squad_agg, "best_f1"
|
||||
), # Best F1 (with varying threshold)
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
"f1": True, # The F-score of predicted tokens versus the gold answer
|
||||
"HasAns_exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
"HasAns_f1": True, # The F-score of predicted tokens versus the gold answer
|
||||
"NoAns_exact": True, # Exact match (the normalized answer exactly match the gold answer)
|
||||
"NoAns_f1": True, # The F-score of predicted tokens versus the gold answer
|
||||
"best_exact": True, # Best exact match (with varying threshold)
|
||||
"best_f1": True, # Best F1 (with varying threshold)
|
||||
}
|
||||
|
||||
+22
-27
@@ -65,23 +65,27 @@ class StoryCloze(Task):
|
||||
return self.dataset["test"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return ' '.join([
|
||||
doc["input_sentence_1"],
|
||||
doc["input_sentence_2"],
|
||||
doc["input_sentence_3"],
|
||||
doc["input_sentence_4"],
|
||||
])
|
||||
return " ".join(
|
||||
[
|
||||
doc["input_sentence_1"],
|
||||
doc["input_sentence_2"],
|
||||
doc["input_sentence_3"],
|
||||
doc["input_sentence_4"],
|
||||
]
|
||||
)
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return ' '.join([
|
||||
doc["input_sentence_1"],
|
||||
doc["input_sentence_2"],
|
||||
doc["input_sentence_3"],
|
||||
doc["input_sentence_4"],
|
||||
])
|
||||
return " ".join(
|
||||
[
|
||||
doc["input_sentence_1"],
|
||||
doc["input_sentence_2"],
|
||||
doc["input_sentence_3"],
|
||||
doc["input_sentence_4"],
|
||||
]
|
||||
)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
clozes = [doc["sentence_quiz1"], doc["sentence_quiz2"]]
|
||||
@@ -89,7 +93,7 @@ class StoryCloze(Task):
|
||||
return " " + clozes[doc["answer_right_ending"] - 1]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
@@ -100,10 +104,7 @@ class StoryCloze(Task):
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
clozes = [doc["sentence_quiz1"], doc["sentence_quiz2"]]
|
||||
lls = [
|
||||
rf.loglikelihood(ctx, " {}".format(choice))[0]
|
||||
for choice in clozes
|
||||
]
|
||||
lls = [rf.loglikelihood(ctx, " {}".format(choice))[0] for choice in clozes]
|
||||
return lls
|
||||
|
||||
def process_results(self, doc, results):
|
||||
@@ -117,10 +118,8 @@ class StoryCloze(Task):
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
gold = doc["answer_right_ending"] - 1
|
||||
acc = 1. if np.argmax(results) == gold else 0.
|
||||
return {
|
||||
"acc": acc
|
||||
}
|
||||
acc = 1.0 if np.argmax(results) == gold else 0.0
|
||||
return {"acc": acc}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
@@ -128,9 +127,7 @@ class StoryCloze(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
@@ -138,9 +135,7 @@ class StoryCloze(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class StoryCloze2016(StoryCloze):
|
||||
|
||||
+67
-99
@@ -61,15 +61,15 @@ class BoolQ(Task):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['passage']
|
||||
|
||||
return doc["passage"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + yesno(doc['label'])
|
||||
return " " + yesno(doc["label"])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
|
||||
ll_yes, _ = rf.loglikelihood(ctx, ' yes')
|
||||
ll_no, _ = rf.loglikelihood(ctx, ' no')
|
||||
ll_yes, _ = rf.loglikelihood(ctx, " yes")
|
||||
ll_no, _ = rf.loglikelihood(ctx, " no")
|
||||
|
||||
return ll_yes, ll_no
|
||||
|
||||
@@ -77,21 +77,15 @@ class BoolQ(Task):
|
||||
ll_yes, ll_no = results
|
||||
gold = doc["label"]
|
||||
|
||||
acc = 1. if (ll_yes > ll_no) == gold else 0.
|
||||
acc = 1.0 if (ll_yes > ll_no) == gold else 0.0
|
||||
|
||||
return {"acc": acc}
|
||||
|
||||
return {
|
||||
"acc": acc
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
class CommitmentBank(Task):
|
||||
@@ -129,27 +123,21 @@ class CommitmentBank(Task):
|
||||
return " {}".format({0: "True", 1: "False", 2: "Neither"}[doc["label"]])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ll_true, _ = rf.loglikelihood(ctx, ' True')
|
||||
ll_false, _ = rf.loglikelihood(ctx, ' False')
|
||||
ll_neither, _ = rf.loglikelihood(ctx, ' Neither')
|
||||
ll_true, _ = rf.loglikelihood(ctx, " True")
|
||||
ll_false, _ = rf.loglikelihood(ctx, " False")
|
||||
ll_neither, _ = rf.loglikelihood(ctx, " Neither")
|
||||
|
||||
return ll_true, ll_false, ll_neither
|
||||
|
||||
def process_results(self, doc, results):
|
||||
gold = doc["label"]
|
||||
pred = np.argmax(results)
|
||||
acc = 1. if pred == gold else 0.
|
||||
acc = 1.0 if pred == gold else 0.0
|
||||
|
||||
return {"acc": acc, "f1": (pred, gold)}
|
||||
|
||||
return {
|
||||
"acc": acc,
|
||||
"f1": (pred, gold)
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True,
|
||||
"f1": True
|
||||
}
|
||||
return {"acc": True, "f1": True}
|
||||
|
||||
@classmethod
|
||||
def cb_multi_fi(cls, items):
|
||||
@@ -161,7 +149,7 @@ class CommitmentBank(Task):
|
||||
f13 = sklearn.metrics.f1_score(y_true=golds == 2, y_pred=preds == 2)
|
||||
avg_f1 = mean([f11, f12, f13])
|
||||
return avg_f1
|
||||
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean,
|
||||
@@ -207,7 +195,7 @@ class Copa(Task):
|
||||
def construct_requests(self, doc, ctx):
|
||||
choice1 = " " + self.convert_choice(doc["choice1"])
|
||||
choice2 = " " + self.convert_choice(doc["choice2"])
|
||||
|
||||
|
||||
ll_choice1, _ = rf.loglikelihood(ctx, choice1)
|
||||
ll_choice2, _ = rf.loglikelihood(ctx, choice2)
|
||||
|
||||
@@ -216,21 +204,15 @@ class Copa(Task):
|
||||
def process_results(self, doc, results):
|
||||
gold = doc["label"]
|
||||
pred = np.argmax(results)
|
||||
acc = 1. if pred == gold else 0.
|
||||
acc = 1.0 if pred == gold else 0.0
|
||||
|
||||
return {"acc": acc}
|
||||
|
||||
return {
|
||||
"acc": acc
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
@staticmethod
|
||||
def convert_choice(choice):
|
||||
@@ -273,28 +255,22 @@ class MultiRC(Task):
|
||||
def construct_requests(self, doc, ctx):
|
||||
true_choice = self.format_answer(answer=doc["answer"], label=True)
|
||||
false_choice = self.format_answer(answer=doc["answer"], label=False)
|
||||
|
||||
ll_true_choice, _ = rf.loglikelihood(ctx, f' {true_choice}')
|
||||
ll_false_choice, _ = rf.loglikelihood(ctx, f' {false_choice}')
|
||||
|
||||
ll_true_choice, _ = rf.loglikelihood(ctx, f" {true_choice}")
|
||||
ll_false_choice, _ = rf.loglikelihood(ctx, f" {false_choice}")
|
||||
|
||||
return ll_true_choice, ll_false_choice
|
||||
|
||||
def process_results(self, doc, results):
|
||||
ll_true_choice, ll_false_choice = results
|
||||
pred = ll_true_choice > ll_false_choice
|
||||
return {
|
||||
"acc": (pred, doc)
|
||||
}
|
||||
|
||||
return {"acc": (pred, doc)}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": acc_all
|
||||
}
|
||||
return {"acc": acc_all}
|
||||
|
||||
|
||||
class ReCoRD(Task):
|
||||
@@ -343,7 +319,7 @@ class ReCoRD(Task):
|
||||
|
||||
@classmethod
|
||||
def format_answer(cls, query, entity):
|
||||
return f' - {query}'.replace("@placeholder", entity)
|
||||
return f" - {query}".replace("@placeholder", entity)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
# We only output the first correct entity in a doc
|
||||
@@ -365,8 +341,12 @@ class ReCoRD(Task):
|
||||
|
||||
prediction = doc["entities"][max_idx]
|
||||
gold_label_set = doc["answers"]
|
||||
f1 = metric_max_over_ground_truths(squad_metrics.compute_f1, prediction, gold_label_set)
|
||||
em = metric_max_over_ground_truths(squad_metrics.compute_exact, prediction, gold_label_set)
|
||||
f1 = metric_max_over_ground_truths(
|
||||
squad_metrics.compute_f1, prediction, gold_label_set
|
||||
)
|
||||
em = metric_max_over_ground_truths(
|
||||
squad_metrics.compute_exact, prediction, gold_label_set
|
||||
)
|
||||
|
||||
return {
|
||||
"f1": f1,
|
||||
@@ -409,19 +389,21 @@ class WordsInContext(Task):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Sentence 1: {}\nSentence 2: {}\nQuestion: Is the word '{}' used in the same way in the" \
|
||||
" two sentences above?\nAnswer:".format(
|
||||
doc["sentence1"],
|
||||
doc["sentence2"],
|
||||
doc["sentence1"][doc["start1"]:doc["end1"]],
|
||||
)
|
||||
return (
|
||||
"Sentence 1: {}\nSentence 2: {}\nQuestion: Is the word '{}' used in the same way in the"
|
||||
" two sentences above?\nAnswer:".format(
|
||||
doc["sentence1"],
|
||||
doc["sentence2"],
|
||||
doc["sentence1"][doc["start1"] : doc["end1"]],
|
||||
)
|
||||
)
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " {}".format({0: "no", 1: "yes"}[doc["label"]])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ll_yes, _ = rf.loglikelihood(ctx, ' yes')
|
||||
ll_no, _ = rf.loglikelihood(ctx, ' no')
|
||||
ll_yes, _ = rf.loglikelihood(ctx, " yes")
|
||||
ll_no, _ = rf.loglikelihood(ctx, " no")
|
||||
|
||||
return ll_yes, ll_no
|
||||
|
||||
@@ -429,21 +411,15 @@ class WordsInContext(Task):
|
||||
ll_yes, ll_no = results
|
||||
gold = doc["label"]
|
||||
|
||||
acc = 1. if (ll_yes > ll_no) == gold else 0.
|
||||
acc = 1.0 if (ll_yes > ll_no) == gold else 0.0
|
||||
|
||||
return {
|
||||
"acc": acc
|
||||
}
|
||||
return {"acc": acc}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
|
||||
class SGWinogradSchemaChallenge(Task):
|
||||
@@ -467,9 +443,7 @@ class SGWinogradSchemaChallenge(Task):
|
||||
if self._training_docs is None:
|
||||
# GPT-3 Paper's format only uses positive examples for fewshot "training"
|
||||
self._training_docs = [
|
||||
doc for doc in
|
||||
self.dataset["train"]
|
||||
if doc["label"]
|
||||
doc for doc in self.dataset["train"] if doc["label"]
|
||||
]
|
||||
return self._training_docs
|
||||
|
||||
@@ -479,25 +453,25 @@ class SGWinogradSchemaChallenge(Task):
|
||||
def doc_to_text(self, doc):
|
||||
raw_passage = doc["text"]
|
||||
# NOTE: HuggingFace span indices are word-based not character-based.
|
||||
pre = " ".join(raw_passage.split()[:doc["span2_index"]])
|
||||
post = raw_passage[len(pre) + len(doc["span2_text"]) + 1:]
|
||||
passage = general_detokenize(pre + " *{}*".format(doc['span2_text']) + post)
|
||||
pre = " ".join(raw_passage.split()[: doc["span2_index"]])
|
||||
post = raw_passage[len(pre) + len(doc["span2_text"]) + 1 :]
|
||||
passage = general_detokenize(pre + " *{}*".format(doc["span2_text"]) + post)
|
||||
noun = doc["span1_text"]
|
||||
pronoun = doc["span2_text"]
|
||||
text = (
|
||||
f"Passage: {passage}\n"
|
||||
+ f"Question: In the passage above, does the pronoun \"*{pronoun}*\" refer to \"*{noun}*\"?\n"
|
||||
+ f'Question: In the passage above, does the pronoun "*{pronoun}*" refer to "*{noun}*"?\n'
|
||||
+ "Answer:"
|
||||
)
|
||||
return text
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + yesno(doc['label'])
|
||||
return " " + yesno(doc["label"])
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
|
||||
ll_yes, _ = rf.loglikelihood(ctx, ' yes')
|
||||
ll_no, _ = rf.loglikelihood(ctx, ' no')
|
||||
ll_yes, _ = rf.loglikelihood(ctx, " yes")
|
||||
ll_no, _ = rf.loglikelihood(ctx, " no")
|
||||
|
||||
return ll_yes, ll_no
|
||||
|
||||
@@ -505,18 +479,12 @@ class SGWinogradSchemaChallenge(Task):
|
||||
ll_yes, ll_no = results
|
||||
gold = doc["label"]
|
||||
|
||||
acc = 1. if (ll_yes > ll_no) == gold else 0.
|
||||
acc = 1.0 if (ll_yes > ll_no) == gold else 0.0
|
||||
|
||||
return {
|
||||
"acc": acc
|
||||
}
|
||||
return {"acc": acc}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
@@ -41,44 +41,57 @@ def create_tasks_from_benchmarks(benchmark_dict):
|
||||
:return: {task_name: task}
|
||||
e.g. {wmt14-fr-en: Task, wmt16-de-en: Task}
|
||||
"""
|
||||
|
||||
def version_of(dataset, language_pair):
|
||||
if language_pair[-2:] in ["zh", "ja"]:
|
||||
return 1 # changed to use jieba/nagisa
|
||||
return 1 # changed to use jieba/nagisa
|
||||
return 0
|
||||
|
||||
return {
|
||||
f"{dataset}-{language_pair}": create_translation_task(dataset, language_pair, version_of(dataset, language_pair))
|
||||
f"{dataset}-{language_pair}": create_translation_task(
|
||||
dataset, language_pair, version_of(dataset, language_pair)
|
||||
)
|
||||
for dataset, language_pairs in benchmark_dict.items()
|
||||
for language_pair in language_pairs
|
||||
}
|
||||
|
||||
|
||||
########################################
|
||||
# Language Specifics
|
||||
########################################
|
||||
|
||||
|
||||
def zh_split(zh_text: List[str]) -> List[str]:
|
||||
"""Chinese splitting"""
|
||||
import jieba
|
||||
|
||||
return [" ".join(jieba.cut(txt.strip())) for txt in zh_text]
|
||||
|
||||
|
||||
def ja_split(ja_text: List[str]) -> List[str]:
|
||||
"""Japanese splitting"""
|
||||
import nagisa
|
||||
|
||||
return [" ".join(nagisa.tagging(txt.strip()).words) for txt in ja_text]
|
||||
|
||||
|
||||
NO_SPACE_LANG = {"zh": zh_split, "ja": ja_split}
|
||||
|
||||
########################################
|
||||
# Tasks
|
||||
########################################
|
||||
|
||||
|
||||
def create_translation_task(dataset, language_pair, version=0):
|
||||
class TranslationTask(GeneralTranslationTask):
|
||||
VERSION = version
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(dataset, language_pair)
|
||||
|
||||
return TranslationTask
|
||||
|
||||
|
||||
class GeneralTranslationTask(Task):
|
||||
VERSION = 0
|
||||
|
||||
@@ -92,8 +105,9 @@ class GeneralTranslationTask(Task):
|
||||
|
||||
def download(self, data_dir=None, cache_dir=None, download_mode=None):
|
||||
# This caches in the users home dir automatically
|
||||
self.src_file, self.ref_file = \
|
||||
sacrebleu.download_test_set(self.sacrebleu_dataset, self.sacrebleu_language_pair)
|
||||
self.src_file, self.ref_file = sacrebleu.download_test_set(
|
||||
self.sacrebleu_dataset, self.sacrebleu_language_pair
|
||||
)
|
||||
self.src_data, self.ref_data = [
|
||||
[line.rstrip() for line in sacrebleu.smart_open(file)]
|
||||
for file in (self.src_file, self.ref_file)
|
||||
@@ -117,10 +131,9 @@ class GeneralTranslationTask(Task):
|
||||
:return: Iterable[obj]
|
||||
A iterable of any object, that doc_to_text can handle
|
||||
"""
|
||||
return [{
|
||||
"src": src,
|
||||
"ref": ref
|
||||
} for src, ref in zip(self.src_data, self.ref_data)]
|
||||
return [
|
||||
{"src": src, "ref": ref} for src, ref in zip(self.src_data, self.ref_data)
|
||||
]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
language_codes = self.sacrebleu_language_pair.split("-")
|
||||
@@ -139,7 +152,7 @@ class GeneralTranslationTask(Task):
|
||||
return " " + doc["ref"] if isinstance(doc["ref"], str) else doc["ref"][0]
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
|
||||
@@ -43,10 +43,10 @@ class TriviaQA(Task):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
return self.dataset['train']
|
||||
return self.dataset["train"]
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset['validation']
|
||||
return self.dataset["validation"]
|
||||
|
||||
def test_docs(self):
|
||||
raise NotImplementedError()
|
||||
@@ -58,10 +58,10 @@ class TriviaQA(Task):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['question']
|
||||
return doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " " + doc['answer']['value']
|
||||
return " " + doc["answer"]["value"]
|
||||
|
||||
def _remove_prefixes(self, aliases):
|
||||
# Optimization: Remove any alias that has a strict prefix elsewhere in the list
|
||||
@@ -75,15 +75,13 @@ class TriviaQA(Task):
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ret = []
|
||||
for alias in self._remove_prefixes(doc['answer']['aliases']):
|
||||
for alias in self._remove_prefixes(doc["answer"]["aliases"]):
|
||||
_, is_prediction = rf.loglikelihood(ctx, " " + alias)
|
||||
ret.append(is_prediction)
|
||||
return ret
|
||||
|
||||
def process_results(self, doc, results):
|
||||
return {
|
||||
"acc": float(any(results))
|
||||
}
|
||||
return {"acc": float(any(results))}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
@@ -91,6 +89,4 @@ class TriviaQA(Task):
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
+57
-70
@@ -82,28 +82,29 @@ class TruthfulQAMultipleChoice(Task):
|
||||
raise NotImplementedError()
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return QA_PROMPT + "\n\nQ: " + doc['question'] + "\nA:"
|
||||
return QA_PROMPT + "\n\nQ: " + doc["question"] + "\nA:"
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['question']
|
||||
return doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " "
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
assert num_fewshot == 0, "TruthfulQA is intended only for the zero-shot setting."
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert (
|
||||
num_fewshot == 0
|
||||
), "TruthfulQA is intended only for the zero-shot setting."
|
||||
return super().fewshot_context(
|
||||
doc=doc,
|
||||
num_fewshot=num_fewshot,
|
||||
rnd=rnd,
|
||||
description=description
|
||||
doc=doc, num_fewshot=num_fewshot, rnd=rnd, description=description
|
||||
)
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
@@ -113,11 +114,15 @@ class TruthfulQAMultipleChoice(Task):
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
|
||||
def get_lls(targets):
|
||||
return [rf.loglikelihood(ctx, " " + t)[0] for t in targets]
|
||||
|
||||
# MC1 and MC2 targets are not always the same set of strings so we collect
|
||||
# likelihoods separately for simpler processing.
|
||||
return get_lls(doc['mc1_targets']["choices"]) + get_lls(doc['mc2_targets']["choices"])
|
||||
return get_lls(doc["mc1_targets"]["choices"]) + get_lls(
|
||||
doc["mc2_targets"]["choices"]
|
||||
)
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
@@ -129,37 +134,29 @@ class TruthfulQAMultipleChoice(Task):
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
|
||||
def mc1(lls):
|
||||
# The gold answers in `mc1_targets` are always first (index = `0`).
|
||||
return np.argmax(lls) == 0
|
||||
|
||||
def mc2(lls):
|
||||
# Split on the first `0` as everything before it is true (`1`).
|
||||
split_idx = list(doc['mc2_targets']["labels"]).index(0)
|
||||
split_idx = list(doc["mc2_targets"]["labels"]).index(0)
|
||||
# Compute the normalized probability mass for the correct answer.
|
||||
ll_true, ll_false = lls[:split_idx], lls[split_idx:]
|
||||
p_true, p_false = np.exp(np.array(ll_true)), np.exp(np.array(ll_false))
|
||||
p_true = p_true / (sum(p_true) + sum(p_false))
|
||||
return sum(p_true)
|
||||
|
||||
split_idx = len(doc['mc1_targets']["choices"])
|
||||
split_idx = len(doc["mc1_targets"]["choices"])
|
||||
mc1_lls, mc2_lls = results[:split_idx], results[split_idx:]
|
||||
return {
|
||||
"mc1": mc1(mc1_lls),
|
||||
"mc2": mc2(mc2_lls)
|
||||
}
|
||||
return {"mc1": mc1(mc1_lls), "mc2": mc2(mc2_lls)}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"mc1": mean,
|
||||
"mc2": mean
|
||||
}
|
||||
return {"mc1": mean, "mc2": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"mc1": True,
|
||||
"mc2": True
|
||||
}
|
||||
return {"mc1": True, "mc2": True}
|
||||
|
||||
|
||||
class TruthfulQAGeneration(Task):
|
||||
@@ -189,44 +186,45 @@ class TruthfulQAGeneration(Task):
|
||||
answer = answer.strip()
|
||||
if len(answer):
|
||||
# Add a period after all answers.
|
||||
if answer[-1] != '.':
|
||||
formatted_answers.append(answer + '.')
|
||||
if answer[-1] != ".":
|
||||
formatted_answers.append(answer + ".")
|
||||
else:
|
||||
formatted_answers.append(answer)
|
||||
return formatted_answers
|
||||
|
||||
def validation_docs(self):
|
||||
for doc in self.dataset["validation"]:
|
||||
incorrect_answers = self._format_answers(doc['incorrect_answers'])
|
||||
correct_answers = self._format_answers(doc['correct_answers'])
|
||||
incorrect_answers = self._format_answers(doc["incorrect_answers"])
|
||||
correct_answers = self._format_answers(doc["correct_answers"])
|
||||
if "I have no comment." not in correct_answers:
|
||||
correct_answers.append("I have no comment.")
|
||||
yield {
|
||||
'question': doc['question'].strip(),
|
||||
'correct_answers': correct_answers,
|
||||
'incorrect_answers': incorrect_answers
|
||||
"question": doc["question"].strip(),
|
||||
"correct_answers": correct_answers,
|
||||
"incorrect_answers": incorrect_answers,
|
||||
}
|
||||
|
||||
def test_docs(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return QA_PROMPT + "\n\nQ: " + doc['question']
|
||||
return QA_PROMPT + "\n\nQ: " + doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return " "
|
||||
|
||||
def fewshot_context(self, doc, num_fewshot, provide_description=None, rnd=None, description=None):
|
||||
assert num_fewshot == 0, "TruthfulQA is intended only for the zero-shot setting."
|
||||
def fewshot_context(
|
||||
self, doc, num_fewshot, provide_description=None, rnd=None, description=None
|
||||
):
|
||||
assert (
|
||||
num_fewshot == 0
|
||||
), "TruthfulQA is intended only for the zero-shot setting."
|
||||
return super().fewshot_context(
|
||||
doc=doc,
|
||||
num_fewshot=num_fewshot,
|
||||
rnd=rnd,
|
||||
description=description
|
||||
doc=doc, num_fewshot=num_fewshot, rnd=rnd, description=description
|
||||
)
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
""" Uses RequestFactory to construct Requests and returns an iterable of
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
@@ -237,7 +235,7 @@ class TruthfulQAGeneration(Task):
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
# TODO: Find a way to cap the number of generated tokens to `50` as in the official implementation.
|
||||
completion = rf.greedy_until(ctx, ['.'])
|
||||
completion = rf.greedy_until(ctx, ["."])
|
||||
return completion
|
||||
|
||||
def process_results(self, doc, results):
|
||||
@@ -251,18 +249,18 @@ class TruthfulQAGeneration(Task):
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
completion = results[0].strip()
|
||||
true_refs, false_refs = doc['correct_answers'], doc['incorrect_answers']
|
||||
true_refs, false_refs = doc["correct_answers"], doc["incorrect_answers"]
|
||||
all_refs = true_refs + false_refs
|
||||
|
||||
# Process the sentence-level BLEURT, BLEU, and ROUGE for similarity measures.
|
||||
|
||||
# BLEURT
|
||||
bleurt_scores_true = self.bleurt.compute(
|
||||
predictions=[completion] * len(true_refs),
|
||||
references=true_refs)['scores']
|
||||
predictions=[completion] * len(true_refs), references=true_refs
|
||||
)["scores"]
|
||||
bleurt_scores_false = self.bleurt.compute(
|
||||
predictions=[completion] * len(false_refs),
|
||||
references=false_refs)['scores']
|
||||
predictions=[completion] * len(false_refs), references=false_refs
|
||||
)["scores"]
|
||||
bleurt_correct = max(bleurt_scores_true)
|
||||
bleurt_incorrect = max(bleurt_scores_false)
|
||||
bleurt_max = bleurt_correct
|
||||
@@ -271,8 +269,8 @@ class TruthfulQAGeneration(Task):
|
||||
|
||||
# BLEU
|
||||
bleu_scores = [self.bleu([[ref]], [completion]) for ref in all_refs]
|
||||
bleu_correct = np.nanmax(bleu_scores[:len(true_refs)])
|
||||
bleu_incorrect = np.nanmax(bleu_scores[len(true_refs):])
|
||||
bleu_correct = np.nanmax(bleu_scores[: len(true_refs)])
|
||||
bleu_incorrect = np.nanmax(bleu_scores[len(true_refs) :])
|
||||
bleu_max = bleu_correct
|
||||
bleu_diff = bleu_correct - bleu_incorrect
|
||||
bleu_acc = int(bleu_correct > bleu_incorrect)
|
||||
@@ -280,23 +278,23 @@ class TruthfulQAGeneration(Task):
|
||||
# ROUGE-N
|
||||
rouge_scores = [self.rouge([ref], [completion]) for ref in all_refs]
|
||||
# ROUGE-1
|
||||
rouge1_scores = [score['rouge1'] for score in rouge_scores]
|
||||
rouge1_correct = np.nanmax(rouge1_scores[:len(true_refs)])
|
||||
rouge1_incorrect = np.nanmax(rouge1_scores[len(true_refs):])
|
||||
rouge1_scores = [score["rouge1"] for score in rouge_scores]
|
||||
rouge1_correct = np.nanmax(rouge1_scores[: len(true_refs)])
|
||||
rouge1_incorrect = np.nanmax(rouge1_scores[len(true_refs) :])
|
||||
rouge1_max = rouge1_correct
|
||||
rouge1_diff = rouge1_correct - rouge1_incorrect
|
||||
rouge1_acc = int(rouge1_correct > rouge1_incorrect)
|
||||
# ROUGE-2
|
||||
rouge2_scores = [score['rouge2'] for score in rouge_scores]
|
||||
rouge2_correct = np.nanmax(rouge2_scores[:len(true_refs)])
|
||||
rouge2_incorrect = np.nanmax(rouge2_scores[len(true_refs):])
|
||||
rouge2_scores = [score["rouge2"] for score in rouge_scores]
|
||||
rouge2_correct = np.nanmax(rouge2_scores[: len(true_refs)])
|
||||
rouge2_incorrect = np.nanmax(rouge2_scores[len(true_refs) :])
|
||||
rouge2_max = rouge2_correct
|
||||
rouge2_diff = rouge2_correct - rouge2_incorrect
|
||||
rouge2_acc = int(rouge2_correct > rouge2_incorrect)
|
||||
# ROUGE-L
|
||||
rougeL_scores = [score['rougeLsum'] for score in rouge_scores]
|
||||
rougeL_correct = np.nanmax(rougeL_scores[:len(true_refs)])
|
||||
rougeL_incorrect = np.nanmax(rougeL_scores[len(true_refs):])
|
||||
rougeL_scores = [score["rougeLsum"] for score in rouge_scores]
|
||||
rougeL_correct = np.nanmax(rougeL_scores[: len(true_refs)])
|
||||
rougeL_incorrect = np.nanmax(rougeL_scores[len(true_refs) :])
|
||||
rougeL_max = rougeL_correct
|
||||
rougeL_diff = rougeL_correct - rougeL_incorrect
|
||||
rougeL_acc = int(rougeL_correct > rougeL_incorrect)
|
||||
@@ -305,19 +303,15 @@ class TruthfulQAGeneration(Task):
|
||||
"bleurt_max": bleurt_max,
|
||||
"bleurt_acc": bleurt_acc,
|
||||
"bleurt_diff": bleurt_diff,
|
||||
|
||||
"bleu_max": bleu_max,
|
||||
"bleu_acc": bleu_acc,
|
||||
"bleu_diff": bleu_diff,
|
||||
|
||||
"rouge1_max": rouge1_max,
|
||||
"rouge1_acc": rouge1_acc,
|
||||
"rouge1_diff": rouge1_diff,
|
||||
|
||||
"rouge2_max": rouge2_max,
|
||||
"rouge2_acc": rouge2_acc,
|
||||
"rouge2_diff": rouge2_diff,
|
||||
|
||||
"rougeL_max": rougeL_max,
|
||||
"rougeL_acc": rougeL_acc,
|
||||
"rougeL_diff": rougeL_diff,
|
||||
@@ -328,19 +322,15 @@ class TruthfulQAGeneration(Task):
|
||||
"bleurt_max": mean,
|
||||
"bleurt_acc": mean,
|
||||
"bleurt_diff": mean,
|
||||
|
||||
"bleu_max": mean,
|
||||
"bleu_acc": mean,
|
||||
"bleu_diff": mean,
|
||||
|
||||
"rouge1_max": mean,
|
||||
"rouge1_acc": mean,
|
||||
"rouge1_diff": mean,
|
||||
|
||||
"rouge2_max": mean,
|
||||
"rouge2_acc": mean,
|
||||
"rouge2_diff": mean,
|
||||
|
||||
"rougeL_max": mean,
|
||||
"rougeL_acc": mean,
|
||||
"rougeL_diff": mean,
|
||||
@@ -351,19 +341,15 @@ class TruthfulQAGeneration(Task):
|
||||
"bleurt_max": True,
|
||||
"bleurt_acc": True,
|
||||
"bleurt_diff": True,
|
||||
|
||||
"bleu_max": True,
|
||||
"bleu_acc": True,
|
||||
"bleu_diff": True,
|
||||
|
||||
"rouge1_max": True,
|
||||
"rouge1_acc": True,
|
||||
"rouge1_diff": True,
|
||||
|
||||
"rouge2_max": True,
|
||||
"rouge2_acc": True,
|
||||
"rouge2_diff": True,
|
||||
|
||||
"rougeL_max": True,
|
||||
"rougeL_acc": True,
|
||||
"rougeL_diff": True,
|
||||
@@ -387,7 +373,7 @@ class TruthfulQAGeneration(Task):
|
||||
force=False,
|
||||
lowercase=False,
|
||||
tokenize="intl",
|
||||
use_effective_order=False
|
||||
use_effective_order=False,
|
||||
).score
|
||||
return score
|
||||
|
||||
@@ -407,6 +393,7 @@ class TruthfulQAGeneration(Task):
|
||||
def _prepare_summary(summary):
|
||||
summary = summary.replace(" . ", ".\n")
|
||||
return summary
|
||||
|
||||
# Accumulate confidence intervals.
|
||||
aggregator = scoring.BootstrapAggregator()
|
||||
for ref, pred in zip(refs, preds):
|
||||
@@ -414,4 +401,4 @@ class TruthfulQAGeneration(Task):
|
||||
pred = _prepare_summary(pred)
|
||||
aggregator.add_scores(scorer.score(ref, pred))
|
||||
result = aggregator.aggregate()
|
||||
return {type: result[type].mid.fmeasure*100 for type in rouge_types}
|
||||
return {type: result[type].mid.fmeasure * 100 for type in rouge_types}
|
||||
|
||||
@@ -65,19 +65,13 @@ class WordUnscrambleTask(Task):
|
||||
def process_results(self, doc, results):
|
||||
pred = results[0]
|
||||
gold = doc["completion"]
|
||||
return {
|
||||
"acc": int(pred == gold)
|
||||
}
|
||||
return {"acc": int(pred == gold)}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
|
||||
class Anagrams1(WordUnscrambleTask):
|
||||
|
||||
+8
-12
@@ -54,20 +54,20 @@ class WebQs(Task):
|
||||
return self.dataset["test"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return "Question: " + doc['question'] + '\nAnswer:'
|
||||
return "Question: " + doc["question"] + "\nAnswer:"
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc['question']
|
||||
return doc["question"]
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
# this picks one answer to be the "correct" one, despite sometimes
|
||||
# this picks one answer to be the "correct" one, despite sometimes
|
||||
# multiple correct answers being possible.
|
||||
# TODO: make sure we're actually handling multi-answer correctly
|
||||
return " " + doc['answers'][0]
|
||||
|
||||
return " " + doc["answers"][0]
|
||||
|
||||
def _remove_prefixes(self, aliases):
|
||||
# Optimization: Remove any alias that has a strict prefix elsewhere in the list
|
||||
# we can do this because if the prefix is acceptable by isgreedy, we can stop looking
|
||||
@@ -81,15 +81,13 @@ class WebQs(Task):
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
ret = []
|
||||
for alias in self._remove_prefixes(doc['answers']):
|
||||
for alias in self._remove_prefixes(doc["answers"]):
|
||||
_, is_prediction = rf.loglikelihood(ctx, " " + alias)
|
||||
ret.append(is_prediction)
|
||||
return ret
|
||||
|
||||
def process_results(self, doc, results):
|
||||
return {
|
||||
"acc": float(any(results))
|
||||
}
|
||||
return {"acc": float(any(results))}
|
||||
|
||||
def aggregation(self):
|
||||
return {
|
||||
@@ -97,6 +95,4 @@ class WebQs(Task):
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Pointer Sentinel Mixture Models
|
||||
https://arxiv.org/pdf/1609.07843.pdf
|
||||
|
||||
The WikiText language modeling dataset is a collection of over 100 million tokens
|
||||
The WikiText language modeling dataset is a collection of over 100 million tokens
|
||||
extracted from the set of verified Good and Featured articles on Wikipedia.
|
||||
|
||||
NOTE: This `Task` is based on WikiText-2.
|
||||
@@ -17,7 +17,7 @@ from lm_eval.base import PerplexityTask
|
||||
|
||||
_CITATION = """
|
||||
@misc{merity2016pointer,
|
||||
title={Pointer Sentinel Mixture Models},
|
||||
title={Pointer Sentinel Mixture Models},
|
||||
author={Stephen Merity and Caiming Xiong and James Bradbury and Richard Socher},
|
||||
year={2016},
|
||||
eprint={1609.07843},
|
||||
|
||||
+132
-138
@@ -1,138 +1,132 @@
|
||||
"""
|
||||
WinoGrande: An Adversarial Winograd Schema Challenge at Scale
|
||||
https://arxiv.org/pdf/1907.10641.pdf
|
||||
|
||||
WinoGrande is a collection of 44k problems, inspired by Winograd Schema Challenge
|
||||
(Levesque, Davis, and Morgenstern 2011), but adjusted to improve the scale and
|
||||
robustness against the dataset-specific bias. Formulated as a fill-in-a-blank
|
||||
task with binary options, the goal is to choose the right option for a given
|
||||
sentence which requires commonsense reasoning.
|
||||
|
||||
NOTE: This evaluation of Winogrande uses partial evaluation as described by
|
||||
Trinh & Le in Simple Method for Commonsense Reasoning (2018).
|
||||
See: https://arxiv.org/abs/1806.02847
|
||||
|
||||
Homepage: https://leaderboard.allenai.org/winogrande/submissions/public
|
||||
"""
|
||||
import numpy as np
|
||||
from lm_eval.base import rf, Task
|
||||
from lm_eval.metrics import mean
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{sakaguchi2019winogrande,
|
||||
title={WinoGrande: An Adversarial Winograd Schema Challenge at Scale},
|
||||
author={Sakaguchi, Keisuke and Bras, Ronan Le and Bhagavatula, Chandra and Choi, Yejin},
|
||||
journal={arXiv preprint arXiv:1907.10641},
|
||||
year={2019}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class Winogrande(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "winogrande"
|
||||
DATASET_NAME = "winogrande_xl"
|
||||
|
||||
answer_to_num = {'1': 0, '2': 1}
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(self.dataset["train"])
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return self.partial_context(doc, doc["option" + doc["answer"]])
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["sentence"]
|
||||
|
||||
@classmethod
|
||||
def partial_context(cls, doc, option):
|
||||
# Substitute the pronoun in the sentence with the specified option
|
||||
# and ignore everything after.
|
||||
pronoun_loc = doc["sentence"].index("_")
|
||||
return doc["sentence"][:pronoun_loc] + option
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return self.partial_target(doc)
|
||||
|
||||
@classmethod
|
||||
def partial_target(cls, doc):
|
||||
# The target is everything after the document specified pronoun.
|
||||
pronoun_loc = doc["sentence"].index("_") + 1
|
||||
return " " + doc["sentence"][pronoun_loc:].strip()
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
target = self.partial_target(doc)
|
||||
lls = []
|
||||
for option in [doc["option1"], doc["option2"]]:
|
||||
partial_ctx = self.partial_context(doc, option)
|
||||
full_ctx = self.append_context(ctx, partial_ctx)
|
||||
lls.append(rf.loglikelihood(full_ctx, target)[0])
|
||||
return lls
|
||||
|
||||
@classmethod
|
||||
def append_context(cls, ctx, partial_ctx):
|
||||
ctx = ctx.split("\n\n") # Each fewshot context is on its own new line.
|
||||
ctx.pop() # Remove the correct context put in by `doc_to_text`.
|
||||
return "\n\n".join([*ctx, partial_ctx]) if ctx else partial_ctx
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
return {
|
||||
"acc": np.argmax(results) == self.answer_to_num[doc["answer"]]
|
||||
}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
"""
|
||||
WinoGrande: An Adversarial Winograd Schema Challenge at Scale
|
||||
https://arxiv.org/pdf/1907.10641.pdf
|
||||
|
||||
WinoGrande is a collection of 44k problems, inspired by Winograd Schema Challenge
|
||||
(Levesque, Davis, and Morgenstern 2011), but adjusted to improve the scale and
|
||||
robustness against the dataset-specific bias. Formulated as a fill-in-a-blank
|
||||
task with binary options, the goal is to choose the right option for a given
|
||||
sentence which requires commonsense reasoning.
|
||||
|
||||
NOTE: This evaluation of Winogrande uses partial evaluation as described by
|
||||
Trinh & Le in Simple Method for Commonsense Reasoning (2018).
|
||||
See: https://arxiv.org/abs/1806.02847
|
||||
|
||||
Homepage: https://leaderboard.allenai.org/winogrande/submissions/public
|
||||
"""
|
||||
import numpy as np
|
||||
from lm_eval.base import rf, Task
|
||||
from lm_eval.metrics import mean
|
||||
|
||||
|
||||
_CITATION = """
|
||||
@article{sakaguchi2019winogrande,
|
||||
title={WinoGrande: An Adversarial Winograd Schema Challenge at Scale},
|
||||
author={Sakaguchi, Keisuke and Bras, Ronan Le and Bhagavatula, Chandra and Choi, Yejin},
|
||||
journal={arXiv preprint arXiv:1907.10641},
|
||||
year={2019}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class Winogrande(Task):
|
||||
VERSION = 0
|
||||
DATASET_PATH = "winogrande"
|
||||
DATASET_NAME = "winogrande_xl"
|
||||
|
||||
answer_to_num = {"1": 0, "2": 1}
|
||||
|
||||
def has_training_docs(self):
|
||||
return True
|
||||
|
||||
def has_validation_docs(self):
|
||||
return True
|
||||
|
||||
def has_test_docs(self):
|
||||
return False
|
||||
|
||||
def training_docs(self):
|
||||
if self._training_docs is None:
|
||||
self._training_docs = list(self.dataset["train"])
|
||||
return self._training_docs
|
||||
|
||||
def validation_docs(self):
|
||||
return self.dataset["validation"]
|
||||
|
||||
def doc_to_text(self, doc):
|
||||
return self.partial_context(doc, doc["option" + doc["answer"]])
|
||||
|
||||
def should_decontaminate(self):
|
||||
return True
|
||||
|
||||
def doc_to_decontamination_query(self, doc):
|
||||
return doc["sentence"]
|
||||
|
||||
@classmethod
|
||||
def partial_context(cls, doc, option):
|
||||
# Substitute the pronoun in the sentence with the specified option
|
||||
# and ignore everything after.
|
||||
pronoun_loc = doc["sentence"].index("_")
|
||||
return doc["sentence"][:pronoun_loc] + option
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return self.partial_target(doc)
|
||||
|
||||
@classmethod
|
||||
def partial_target(cls, doc):
|
||||
# The target is everything after the document specified pronoun.
|
||||
pronoun_loc = doc["sentence"].index("_") + 1
|
||||
return " " + doc["sentence"][pronoun_loc:].strip()
|
||||
|
||||
def construct_requests(self, doc, ctx):
|
||||
"""Uses RequestFactory to construct Requests and returns an iterable of
|
||||
Requests which will be sent to the LM.
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param ctx: str
|
||||
The context string, generated by fewshot_context. This includes the natural
|
||||
language description, as well as the few shot examples, and the question
|
||||
part of the document for `doc`.
|
||||
"""
|
||||
target = self.partial_target(doc)
|
||||
lls = []
|
||||
for option in [doc["option1"], doc["option2"]]:
|
||||
partial_ctx = self.partial_context(doc, option)
|
||||
full_ctx = self.append_context(ctx, partial_ctx)
|
||||
lls.append(rf.loglikelihood(full_ctx, target)[0])
|
||||
return lls
|
||||
|
||||
@classmethod
|
||||
def append_context(cls, ctx, partial_ctx):
|
||||
ctx = ctx.split("\n\n") # Each fewshot context is on its own new line.
|
||||
ctx.pop() # Remove the correct context put in by `doc_to_text`.
|
||||
return "\n\n".join([*ctx, partial_ctx]) if ctx else partial_ctx
|
||||
|
||||
def process_results(self, doc, results):
|
||||
"""Take a single document and the LM results and evaluates, returning a
|
||||
dict where keys are the names of submetrics and values are the values of
|
||||
the metric for that one document
|
||||
|
||||
:param doc:
|
||||
The document as returned from training_docs, validation_docs, or test_docs.
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
return {"acc": np.argmax(results) == self.answer_to_num[doc["answer"]]}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
:returns: {str: [float] -> float}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
:returns: {str: bool}
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {"acc": True}
|
||||
|
||||
+18
-13
@@ -40,8 +40,19 @@ class WinogradSchemaChallenge273(Task):
|
||||
DATASET_PATH = "winograd_wsc"
|
||||
DATASET_NAME = "wsc273"
|
||||
|
||||
upper_pronouns = ["A", "An", "The", "She", "He",
|
||||
"It", "They", "My", "His", "Her", "Their"]
|
||||
upper_pronouns = [
|
||||
"A",
|
||||
"An",
|
||||
"The",
|
||||
"She",
|
||||
"He",
|
||||
"It",
|
||||
"They",
|
||||
"My",
|
||||
"His",
|
||||
"Her",
|
||||
"Their",
|
||||
]
|
||||
|
||||
def has_training_docs(self):
|
||||
return False
|
||||
@@ -68,7 +79,7 @@ class WinogradSchemaChallenge273(Task):
|
||||
option += "'s"
|
||||
# Appropriately lowercase the pronoun in the option.
|
||||
pronoun = option.split()[0]
|
||||
start_of_sentence = doc["text"][doc['pronoun_loc'] - 2] == '.'
|
||||
start_of_sentence = doc["text"][doc["pronoun_loc"] - 2] == "."
|
||||
if not start_of_sentence and pronoun in self.upper_pronouns:
|
||||
return option.replace(pronoun, pronoun.lower())
|
||||
return option
|
||||
@@ -95,7 +106,7 @@ class WinogradSchemaChallenge273(Task):
|
||||
def partial_context(cls, doc, option):
|
||||
# Substitute the pronoun in the original text with the specified
|
||||
# option and ignore everything after.
|
||||
return doc["text"][:doc["pronoun_loc"]] + option
|
||||
return doc["text"][: doc["pronoun_loc"]] + option
|
||||
|
||||
def doc_to_target(self, doc):
|
||||
return self.partial_target(doc)
|
||||
@@ -141,9 +152,7 @@ class WinogradSchemaChallenge273(Task):
|
||||
:param results:
|
||||
The results of the requests created in construct_requests.
|
||||
"""
|
||||
return {
|
||||
"acc": np.argmax(results) == doc["label"]
|
||||
}
|
||||
return {"acc": np.argmax(results) == doc["label"]}
|
||||
|
||||
def aggregation(self):
|
||||
"""
|
||||
@@ -151,9 +160,7 @@ class WinogradSchemaChallenge273(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
functions that aggregate a list of metrics
|
||||
"""
|
||||
return {
|
||||
"acc": mean
|
||||
}
|
||||
return {"acc": mean}
|
||||
|
||||
def higher_is_better(self):
|
||||
"""
|
||||
@@ -161,6 +168,4 @@ class WinogradSchemaChallenge273(Task):
|
||||
A dictionary where keys are the names of submetrics and values are
|
||||
whether a higher value of the submetric is better
|
||||
"""
|
||||
return {
|
||||
"acc": True
|
||||
}
|
||||
return {"acc": True}
|
||||
|
||||
+47
-32
@@ -34,6 +34,7 @@ def simple_parse_args_string(args_string):
|
||||
args_dict[k] = v
|
||||
return args_dict
|
||||
|
||||
|
||||
def join_iters(iters):
|
||||
for iter in iters:
|
||||
yield from iter
|
||||
@@ -46,23 +47,26 @@ def chunks(iter, n):
|
||||
if len(arr) == n:
|
||||
yield arr
|
||||
arr = []
|
||||
|
||||
if arr: yield arr
|
||||
|
||||
if arr:
|
||||
yield arr
|
||||
|
||||
|
||||
def group(arr, fn):
|
||||
res = collections.defaultdict(list)
|
||||
|
||||
for ob in arr:
|
||||
res[fn(ob)].append(ob)
|
||||
|
||||
|
||||
return list(res.values())
|
||||
|
||||
|
||||
def general_detokenize(string):
|
||||
string = string.replace(" n't", "n't")
|
||||
string = string.replace(" )", ")")
|
||||
string = string.replace("( ", "(")
|
||||
string = string.replace("\" ", "\"")
|
||||
string = string.replace(" \"", "\"")
|
||||
string = string.replace('" ', '"')
|
||||
string = string.replace(' "', '"')
|
||||
string = re.sub(r" (['.,])", r"\1", string)
|
||||
return string
|
||||
|
||||
@@ -94,10 +98,7 @@ def get_rolling_token_windows(token_list, prefix_token, max_seq_len, context_len
|
||||
|
||||
# Special handling for first window: predict all tokens
|
||||
first_seq_len = min(max_seq_len, len(token_list))
|
||||
yield (
|
||||
[prefix_token] + token_list[:first_seq_len - 1],
|
||||
token_list[:first_seq_len]
|
||||
)
|
||||
yield ([prefix_token] + token_list[: first_seq_len - 1], token_list[:first_seq_len])
|
||||
predicted += first_seq_len
|
||||
|
||||
while predicted < len(token_list):
|
||||
@@ -105,61 +106,66 @@ def get_rolling_token_windows(token_list, prefix_token, max_seq_len, context_len
|
||||
window_end = predicted + window_pred_len
|
||||
|
||||
yield (
|
||||
token_list[window_end - max_seq_len - 1:window_end - 1],
|
||||
token_list[window_end - window_pred_len:window_end],
|
||||
token_list[window_end - max_seq_len - 1 : window_end - 1],
|
||||
token_list[window_end - window_pred_len : window_end],
|
||||
)
|
||||
predicted += window_pred_len
|
||||
|
||||
|
||||
def make_disjoint_window(pair):
|
||||
""" Takes output from get_rolling_token_windows and makes the context not overlap with the continuation """
|
||||
"""Takes output from get_rolling_token_windows and makes the context not overlap with the continuation"""
|
||||
|
||||
a, b = pair
|
||||
|
||||
return a[:-(len(b) - 1)], b
|
||||
return a[: -(len(b) - 1)], b
|
||||
|
||||
|
||||
class Reorderer:
|
||||
def __init__(self, arr, fn):
|
||||
self.size = len(arr)
|
||||
arr = list(enumerate(arr))
|
||||
arr = group(arr, lambda x: fn(x[1]))
|
||||
arr = [
|
||||
([y[0] for y in x], x[0][1]) for x in arr
|
||||
]
|
||||
arr = [([y[0] for y in x], x[0][1]) for x in arr]
|
||||
arr.sort(key=lambda x: fn(x[1]))
|
||||
|
||||
self.arr = arr
|
||||
|
||||
|
||||
|
||||
def get_reordered(self):
|
||||
return [x[1] for x in self.arr]
|
||||
|
||||
|
||||
def get_original(self, newarr):
|
||||
res = [None] * self.size
|
||||
cov = [False] * self.size
|
||||
|
||||
for (inds, _), v in zip(self.arr, newarr):
|
||||
for ind in inds:
|
||||
for ind in inds:
|
||||
res[ind] = v
|
||||
cov[ind] = True
|
||||
|
||||
|
||||
assert all(cov)
|
||||
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def positional_deprecated(fn):
|
||||
"""
|
||||
A decorator to nudge users into passing only keyword args (`kwargs`) to the
|
||||
A decorator to nudge users into passing only keyword args (`kwargs`) to the
|
||||
wrapped function, `fn`.
|
||||
"""
|
||||
|
||||
@functools.wraps(fn)
|
||||
def _wrapper(*args, **kwargs):
|
||||
if len(args) != 1 if inspect.ismethod(fn) else 0:
|
||||
print(f"WARNING: using {fn.__name__} with positional arguments is "
|
||||
if len(args) != 1 if inspect.ismethod(fn) else 0:
|
||||
print(
|
||||
f"WARNING: using {fn.__name__} with positional arguments is "
|
||||
"deprecated and will be disallowed in a future version of "
|
||||
"lm-evaluation-harness!")
|
||||
"lm-evaluation-harness!"
|
||||
)
|
||||
return fn(*args, **kwargs)
|
||||
|
||||
return _wrapper
|
||||
|
||||
|
||||
@positional_deprecated
|
||||
def find_test_root(start_path: pathlib.Path) -> pathlib.Path:
|
||||
"""
|
||||
@@ -169,12 +175,14 @@ def find_test_root(start_path: pathlib.Path) -> pathlib.Path:
|
||||
cur_path = start_path.resolve()
|
||||
max_layers = 3
|
||||
for _ in range(max_layers):
|
||||
if (cur_path / 'tests' / 'test_version_stable.py').exists():
|
||||
if (cur_path / "tests" / "test_version_stable.py").exists():
|
||||
return cur_path
|
||||
else:
|
||||
cur_path = cur_path.parent.resolve()
|
||||
raise FileNotFoundError(f"Unable to find package root within {max_layers} upwards" +\
|
||||
f"of {start_path}")
|
||||
raise FileNotFoundError(
|
||||
f"Unable to find package root within {max_layers} upwards" + f"of {start_path}"
|
||||
)
|
||||
|
||||
|
||||
@positional_deprecated
|
||||
def run_task_tests(task_list: List[str]):
|
||||
@@ -182,9 +190,16 @@ def run_task_tests(task_list: List[str]):
|
||||
Find the package root and run the tests for the given tasks
|
||||
"""
|
||||
package_root = find_test_root(start_path=pathlib.Path(__file__))
|
||||
task_string = ' or '.join(task_list)
|
||||
args = [f'{package_root}/tests/test_version_stable.py', f'--rootdir={package_root}', '-k', f'{task_string}']
|
||||
task_string = " or ".join(task_list)
|
||||
args = [
|
||||
f"{package_root}/tests/test_version_stable.py",
|
||||
f"--rootdir={package_root}",
|
||||
"-k",
|
||||
f"{task_string}",
|
||||
]
|
||||
sys.path.append(str(package_root))
|
||||
pytest_return_val = pytest.main(args)
|
||||
if pytest_return_val:
|
||||
raise ValueError(f"Not all tests for the specified tasks ({task_list}) ran successfully! Error code: {pytest_return_val}")
|
||||
raise ValueError(
|
||||
f"Not all tests for the specified tasks ({task_list}) ran successfully! Error code: {pytest_return_val}"
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ from lm_eval import tasks, evaluator
|
||||
|
||||
logging.getLogger("openai").setLevel(logging.WARNING)
|
||||
|
||||
|
||||
class MultiChoice:
|
||||
def __init__(self, choices):
|
||||
self.choices = choices
|
||||
@@ -23,24 +24,26 @@ class MultiChoice:
|
||||
for choice in self.choices:
|
||||
yield choice
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--model', required=True)
|
||||
parser.add_argument('--model_args', default="")
|
||||
parser.add_argument('--tasks', default=None, choices=MultiChoice(tasks.ALL_TASKS))
|
||||
parser.add_argument('--provide_description', action="store_true")
|
||||
parser.add_argument('--num_fewshot', type=int, default=0)
|
||||
parser.add_argument('--batch_size', type=int, default=None)
|
||||
parser.add_argument('--device', type=str, default=None)
|
||||
parser.add_argument('--output_path', default=None)
|
||||
parser.add_argument('--limit', type=int, default=None)
|
||||
parser.add_argument('--no_cache', action="store_true")
|
||||
parser.add_argument('--decontamination_ngrams_path', default=None)
|
||||
parser.add_argument('--description_dict_path', default=None)
|
||||
parser.add_argument('--check_integrity', action="store_true")
|
||||
parser.add_argument("--model", required=True)
|
||||
parser.add_argument("--model_args", default="")
|
||||
parser.add_argument("--tasks", default=None, choices=MultiChoice(tasks.ALL_TASKS))
|
||||
parser.add_argument("--provide_description", action="store_true")
|
||||
parser.add_argument("--num_fewshot", type=int, default=0)
|
||||
parser.add_argument("--batch_size", type=int, default=None)
|
||||
parser.add_argument("--device", type=str, default=None)
|
||||
parser.add_argument("--output_path", default=None)
|
||||
parser.add_argument("--limit", type=int, default=None)
|
||||
parser.add_argument("--no_cache", action="store_true")
|
||||
parser.add_argument("--decontamination_ngrams_path", default=None)
|
||||
parser.add_argument("--description_dict_path", default=None)
|
||||
parser.add_argument("--check_integrity", action="store_true")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
# Returns a list containing all values of the source_list that
|
||||
# match at least one of the patterns
|
||||
def pattern_match(patterns, source_list):
|
||||
@@ -50,13 +53,16 @@ def pattern_match(patterns, source_list):
|
||||
task_names.add(matching)
|
||||
return list(task_names)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
|
||||
assert not args.provide_description # not implemented
|
||||
|
||||
|
||||
if args.limit:
|
||||
print("WARNING: --limit SHOULD ONLY BE USED FOR TESTING. REAL METRICS SHOULD NOT BE COMPUTED USING LIMIT.")
|
||||
print(
|
||||
"WARNING: --limit SHOULD ONLY BE USED FOR TESTING. REAL METRICS SHOULD NOT BE COMPUTED USING LIMIT."
|
||||
)
|
||||
|
||||
if args.tasks is None:
|
||||
task_names = tasks.ALL_TASKS
|
||||
@@ -67,7 +73,7 @@ def main():
|
||||
|
||||
description_dict = {}
|
||||
if args.description_dict_path:
|
||||
with open(args.description_dict_path, 'r') as f:
|
||||
with open(args.description_dict_path, "r") as f:
|
||||
description_dict = json.load(f)
|
||||
|
||||
results = evaluator.simple_evaluate(
|
||||
@@ -81,10 +87,10 @@ def main():
|
||||
limit=args.limit,
|
||||
description_dict=description_dict,
|
||||
decontamination_ngrams_path=args.decontamination_ngrams_path,
|
||||
check_integrity=args.check_integrity
|
||||
check_integrity=args.check_integrity,
|
||||
)
|
||||
|
||||
dumped = json.dumps(results, indent=2)
|
||||
dumped = json.dumps(results, indent=2)
|
||||
print(dumped)
|
||||
|
||||
if args.output_path:
|
||||
|
||||
@@ -34,4 +34,4 @@
|
||||
196565318,
|
||||
203583306
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
janitor.py contains a script to remove benchmark data contamination from training data sets.
|
||||
janitor.py contains a script to remove benchmark data contamination from training data sets.
|
||||
It uses the approach described in the [GPT-3 paper](https://arxiv.org/abs/2005.14165).
|
||||
|
||||
## Algorithm
|
||||
1) Collects all contamination text files that are to be removed from training data
|
||||
2) Filters training data by finding `N`gram matches between the training data
|
||||
2) Filters training data by finding `N`gram matches between the training data
|
||||
and any contamination
|
||||
1) `N`grams ignore case and punctation and are split on whitespace.
|
||||
2) Matching `N`gram substrings are removed, as is a `window_to_remove` character window around
|
||||
1) `N`grams ignore case and punctation and are split on whitespace.
|
||||
2) Matching `N`gram substrings are removed, as is a `window_to_remove` character window around
|
||||
the match, splitting the training data into chunks
|
||||
3) Any chunks less than `minimum_slice_length` are removed
|
||||
4) Training data sets split into more than `too_dirty_cutoff` are considered
|
||||
completey contaminated and removed
|
||||
|
||||
|
||||
OpenAI used:
|
||||
```
|
||||
ngram_n = 13
|
||||
@@ -31,4 +31,3 @@ c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) janitor
|
||||
```
|
||||
|
||||
If your your compiler isn't linked to python, you may need to add to the above `-undefined dynamic_lookup`
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user