Anserini Documentation

repository·master·Indexed 22 days ago

https://github.com/castorini/anserini

A toolkit built on top of Apache Lucene designed for reproducible information retrieval (IR) research. Anserini provides tools for indexing custom collections in MS MARCO JSONL format and performing retrieval, with a Python interface available via Pyserini. The toolkit supports Lucene 10.4.0 (v2.0.0) and maintains readability for Lucene 9 indexes.

Tokens
139.5K
Snippets
506
Records
548
Agent score
78%

What's inside Anserini

  1. Understand the Anserini Regressions Log

    master
    The Anserini Regressions Log tracks changes to regression tests that affect retrieval effectiveness. It documents when new regression tests are added, when existing ones are removed, and when effectiveness numbers are updated due to changes in underlying components (like analyzers or model implementations). Developers can use this log to investigate why retrieval results or effectiveness metrics have changed over time in the project.
  2. How retrieval systems are evaluated

    master

    To measure the quality of a retrieval system, you compare its output against relevance judgments (also known as qrels).

    Relevance Judgments (qrels): These are artifacts that map queries to documents with a relevance score. They are typically represented as triples: [query_id] [document_id] [relevance_score]

    Example format:

    q1 doc23 0
    q1 doc452 1
    q1 doc536 0
    q2 doc97 0

    (In this example, doc452 is relevant to q1, while doc23 and doc536 are not).

    Metrics: Metrics quantify the 'goodness' of a ranked list. A common example is Precision at 10 (P@10), which calculates the fraction of the top 10 documents that are relevant according to the qrels. The final system performance is typically the average of these scores across all queries.

  3. Add metadata to ONNX models for optimization

    master

    To facilitate the optimization process, metadata (such as model_type, num_heads, and hidden_size) should be embedded into the ONNX model. This is done by loading the exported ONNX model and adding properties to metadata_props before saving.

    # Example of adding metadata to an ONNX model
    model_type = model.config.model_type
    num_heads = model.config.num_attention_heads
    hidden_size = model.config.hidden_size
    
    onnx_model = onnx.load(onnx_path)
    meta = onnx_model.metadata_props.add()
    meta.key, meta.value = 'model_type', model_type
    meta = onnx_model.metadata_props.add()
    meta.key, meta.value = 'num_heads', str(num_heads)
    meta = onnx_model.metadata_props.add()
    meta.key, meta.value = 'hidden_size', str(hidden_size)
    
    onnx.save(onnx_model, onnx_path)
  4. Lucene version compatibility and index readability

    master

    Anserini was upgraded to Lucene 10.4.0 as part of v2.0.0.

    • Lucene 9 indexes: Remain readable by Anserini.
    • Lucene 10 indexes: Older versions of Anserini code are unable to read indexes generated by Lucene 10.
  5. Reproduce experiments from document collections

    master

    Anserini provides an end-to-end framework for reproduction experiments via the io.anserini.reproduce.ReproduceFromDocumentCollection driver. This driver automates the entire pipeline from raw data to evaluated results.

    When running a reproduction, the driver performs these steps in order:

    1. Build the index: Constructs the index from scratch using the raw document collection.
    2. Verify index statistics: Performs a sanity check to ensure the index was built correctly.
    3. Perform retrieval runs: Executes searches using various settings.
    4. Evaluate runs: Evaluates the effectiveness of the retrieval runs and verifies the results.

    Documentation pages for these experiments are automatically generated from templates located in src/main/resources/reproduce/from-document-collection/docgen.

    bin/run.sh io.anserini.reproduce.ReproduceFromDocumentCollection --index --verify --search --config cacm
  6. Understand SourceDocument parsing logic (contents vs raw)

    master

    In Anserini, the SourceDocument class distinguishes between raw() and contents() to ensure collections handle their own parsing logic:

    • raw(): Returns the raw JSON data of the document.
    • contents(): Returns the extracted, parsed content (e.g., article text) intended for indexing.

    This separation ensures that 'empty document checks' are performed on the actual parsed content rather than the JSON wrapper, providing a more accurate count of valid documents. When implementing or extending collections, ensure parsing logic resides within the collection implementation to satisfy this principle.

  7. Important: Elastirini is deprecated

    master
    ⚠️ Note: Support for Solr integration (Elastirini) was removed in Anserini on August 2, 2022 (commit 272565). The features described in this documentation are no longer available. This guide is retained for historical purposes only.
  8. Note on Lucene version impact on effectiveness

    master
    Anserini was upgraded to Lucene 7 in commit e71df7aee42c7776a63b9845600a4075632fa11c. This upgrade changes the retrieval results compared to the previous Lucene 6 version. When comparing effectiveness metrics (like AP, NDCG, or P10) against official TREC runs or older reproductions, ensure you are aware of which Lucene version the Anserini build is using, as it directly impacts the scores.
  9. How SpladeExportWrapper handles output conversion

    master

    The SpladeExportWrapper is a PyTorch nn.Module used during the conversion process to add a 'layer' of logic that transforms raw model outputs into sparse vectors compatible with Anserini.

    It performs the following steps in its forward pass:

    1. Passes input_ids and attention_mask to the underlying SPLADE model.
    2. Applies ReLU and log1p to the logits.
    3. Multiplies the result by the attention_mask to zero out padding.
    4. Uses torch.max across the sequence dimension to produce a sparse vector.
    5. Returns the non-zero indices and their corresponding values.
    class SpladeExportWrapper(nn.Module):
        def __init__(self, splade_model):
            super().__init__()
            self.splade = splade_model
    
        def forward(self, input_ids, attention_mask, token_type_ids):
            # Use token_type_ids in a no-op way to force ONNX to retain it
            dummy = token_type_ids.sum() * 0.0
            outputs = self.splade(input_ids=input_ids, attention_mask=attention_mask)
            logits = outputs.logits
            relu = torch.relu(logits)
            log1p = torch.log1p(relu)
            sparse_vec = torch.max(log1p * attention_mask.unsqueeze(-1), dim=1).values
            nonzero = sparse_vec.nonzero(as_tuple=True)
            values = sparse_vec[nonzero]
            return nonzero[1], values + dummy
  10. Understand MS MARCO data formats

    master

    When working with MS MARCO in Anserini, the following data structures are used:

    Collection (collection.tsv or JSONL)

    • TSV format: Two columns: docid (unique identifier) and the passage text.
    • JSONL format: One JSON object per line, used by Anserini for indexing.

    Queries (queries.tsv)

    • Two columns: qid (unique query identifier) and the query text.

    Relevance Judgments (qrels.tsv)

    Standard format for relevance judgments:

    1. qid: Query identifier.
    2. 0: Historical artifact (almost always 0).
    3. docid: Document/passage identifier.
    4. relevance: The judgment (e.g., 0 for not relevant, 1 for relevant).
  11. Core concepts of the retrieval problem

    master

    In information retrieval (search), the goal is to solve the retrieval problem: given an information need expressed as a query ($q$), return a ranked list of $k$ documents ($d_1, d_2, ext{...}, d_k$) from a finite collection (or corpus) $C$ that maximizes a specific metric (e.g., nDCG, AP).

    Key components include:

    • Query: The input to the retrieval system representing the user's information need.
    • Collection/Corpus: The set of documents being searched.
    • Document: A discrete information object (webpage, PDF, passage, etc.) identified by a unique ID.
    • Relevance: The relationship between a query and a document (e.g., does this document contain the information sought?). Relevance can be binary (relevant/not relevant) or graded (e.g., a Likert scale).