Skip to content

Add IFIR in retrieval dataset. #2682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

SighingSnow
Copy link

Code Quality

  • Code Formatted: Format the code using make lint to maintain consistent style.

Documentation

  • Updated Documentation: Add or update documentation to reflect the changes introduced in this PR.

Testing

  • New Tests Added: Write tests to cover new functionality. Validate with make test-with-coverage.
  • Tests Passed: Run tests locally using make test or make test-with-coverage to ensure no existing functionality is broken.

Adding datasets checklist

Reason for dataset addition: ...

  • I have run the following models on the task (adding the results to the pr). These can be run using the mteb -m {model_name} -t {task_name} command.
    • sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
    • intfloat/multilingual-e5-small
  • I have checked that the performance is neither trivial (both models gain close to perfect scores) nor random (both models gain close to random scores).
  • If the dataset is too big (e.g. >2048 examples), considering using self.stratified_subsampling() under dataset_transform()
  • I have filled out the metadata object in the dataset file (find documentation on it here).
  • Run tests locally to make sure nothing is broken using make test.
  • Run the formatter to format the code using make lint.

Comment on lines 11 to 80
DOMAINS = [
"fiqa",
"nfcorpus",
"scifact_open",
"aila",
"fire",
"pm",
"cds"
]

DOMAINS_langs = {split: ["eng"] for split in DOMAINS}


def load_ifir_data(
self,
path: str,
domains: list,
eval_splits: list,
cache_dir: str | None = None,
revision: str | None = None,
):
corpus = {domain: {split: None for split in eval_splits} for domain in DOMAINS}
queries = {domain: {split: None for split in eval_splits} for domain in DOMAINS}
relevant_docs = {
domain: {split: None for split in eval_splits} for domain in DOMAINS
}

for domain in domains:
domain_corpus = datasets.load_dataset(
path, "corpus", split=domain, cache_dir=cache_dir, revision=revision
)
domain_queries = datasets.load_dataset(
path, "queries", split=domain, cache_dir=cache_dir, revision=revision
)
qrels = datasets.load_dataset(
path, "qrels", split=domain, cache_dir=cache_dir, revision=revision
)
corpus[domain]["test"] = {
e["_id"]: {"text": e["text"]} for e in domain_corpus
}
queries[domain]["test"] = {
e["_id"]: e["text"] for e in domain_queries
}
relevant_docs[domain]["test"] = {}

for e in qrels:
qid = e["query-id"]
doc_id = e["doc-id"]
if qid not in relevant_docs[domain]["test"]:
relevant_docs[domain]["test"][qid] = defaultdict(dict)
relevant_docs[domain]["test"][qid].update({doc_id: 1})

corpus = datasets.DatasetDict(corpus)
queries = datasets.DatasetDict(queries)
relevant_docs = datasets.DatasetDict(relevant_docs)
return corpus, queries, relevant_docs


def load_data(self, **kwargs):
if self.data_loaded:
return

self.corpus, self.queries, self.relevant_docs = self.load_ifir_data(
path=self.metadata_dict["dataset"]["path"],
domains=DOMAINS,
eval_splits=self.metadata_dict["eval_splits"],
cache_dir=kwargs.get("cache_dir", None),
revision=self.metadata_dict["dataset"]["revision"],
)
self.data_loaded = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move functions to the class? I think you've copied them from BrightRetrieval, that have this structure because it has 2 different tasks from same repo

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, no problem.

Comment on lines +11 to +19
DOMAINS = [
"fiqa",
"nfcorpus",
"scifact_open",
"aila",
"fire",
"pm",
"cds"
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, the implementation is the same.

However, we construct a new dataset based on these datasets.

@Samoed
Copy link
Member

Samoed commented May 9, 2025

Overall I think it would be better to integrate your tasks seperatly and after that create benchmark in benchmarks.py

@SighingSnow
Copy link
Author

SighingSnow commented May 9, 2025

Overall I think it would be better to integrate your tasks seperatly and after that create benchmark in benchmarks.py

Maybe like RAR-b ? They seperate their tasks. But I think the implementation maybe not that elegant.

Our paper measures the instruction-following retrieval ability covering these domains. I think it's similar to BRIGHT to some extent.

@Samoed
Copy link
Member

Samoed commented May 9, 2025

Yes, you can do like this

@KennethEnevoldsen
Copy link
Contributor

@SighingSnow it is possible to create an AggregateTask, that simply aggregates scores across the individual tasks (instead of implementing it as one task). It seems like this is kind what you are doing here.

@SighingSnow
Copy link
Author

Thank u. I will revise my code. And it will be done maybe next week.

@SighingSnow SighingSnow closed this by deleting the head repository May 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants