| import os |
| import argparse |
| from collections import namedtuple |
| from datasets import load_dataset |
| import tqdm |
|
|
| from colbert import Indexer, Searcher, IndexUpdater |
| from colbert.infra import ColBERTConfig, RunConfig, Run |
|
|
| SquadExample = namedtuple("SquadExample", "id title context question answers") |
|
|
| nbits = 1 |
| doc_maxlen = 180 |
| experiment = f"removetest.nbits={nbits}" |
|
|
|
|
| def build_index_and_init_searcher(checkpoint, collection, experiment_dir): |
| with Run().context(RunConfig(nranks=1)): |
| config = ColBERTConfig( |
| doc_maxlen=doc_maxlen, |
| nbits=nbits, |
| root=experiment_dir, |
| experiment=experiment, |
| ) |
| indexer = Indexer(checkpoint, config=config) |
| indexer.index(name=experiment, collection=collection, overwrite=True) |
| index_path = indexer.get_index() |
|
|
| config = ColBERTConfig( |
| root=experiment_dir, |
| experiment=experiment, |
| ) |
| searcher = Searcher( |
| index=experiment, |
| config=config, |
| ) |
|
|
| return searcher, index_path |
|
|
|
|
| def get_squad_split(squad, split="validation"): |
| fields = squad[split].features |
| data = zip(*[squad[split][field] for field in fields]) |
| return [ |
| SquadExample(eid, title, context, question, answers["text"]) |
| for eid, title, context, question, answers in data |
| ] |
|
|
|
|
| def main(args): |
| checkpoint = args.checkpoint |
| collection = args.collection |
| experiment_dir = args.expdir |
|
|
| |
| k = 5 |
| searcher, index_path = build_index_and_init_searcher( |
| checkpoint, collection, experiment_dir |
| ) |
| squad = load_dataset("squad") |
| squad_dev = get_squad_split(squad) |
| question = squad_dev[10].question |
| all_tests_passed = True |
|
|
| |
| results = searcher.search(question, k=k) |
| top_k_ids = [] |
| for passage_id, passage_rank, passage_score in zip(*results): |
| top_k_ids.append(passage_id) |
| print(f"Initial search top results: {top_k_ids}") |
|
|
| |
| config = ColBERTConfig( |
| doc_maxlen=doc_maxlen, |
| nbits=nbits, |
| root=experiment_dir, |
| experiment=experiment, |
| ) |
|
|
| index_updater = IndexUpdater(config, searcher, checkpoint) |
|
|
| |
| n = 1 |
| index_updater.remove(top_k_ids[:n]) |
|
|
| |
| results = searcher.search(question, k=k) |
| top_k_ids_after = [] |
| for passage_id, passage_rank, passage_score in zip(*results): |
| top_k_ids_after.append(passage_id) |
|
|
| |
| print(f"Top results after removing the top passage: {top_k_ids_after}") |
| if top_k_ids[n:] == top_k_ids_after[:-n] and top_k_ids_after[-n:] != top_k_ids[:n]: |
| print("REMOVAL SUCCEEDED") |
| else: |
| print(top_k_ids) |
| print(top_k_ids_after) |
|
|
| print("REMOVAL FAILED!!!") |
| all_tests_passed = False |
|
|
| |
| passage_removed = "Diego on May 24, 1984 during their May 23–25, 1984 meetings in Washington, D.C. This was the first Super Bowl to be played at Jack Murphy Stadium (now currently known as Qualcomm Stadium) in San Diego, California. Fourteen cities were part of the bidding process, which was scheduled to award four Super Bowls (XXI, XXII, XXIII, and XXIV). The bidding cities included: Anaheim, Detroit, Houston, Jacksonville, Miami, Minneapolis, New Orleans, Pasadena, Philadelphia, San Francisco, San Diego, Seattle, Tampa, and Tempe. The Philadelphia host committee assembled what was considered a strong, but long-shot bid, hoping to win the first outdoor Super" |
| new_pids = index_updater.add([passage_removed]) |
|
|
| |
| results = searcher.search(question, k=k) |
| top_k_ids_after_append = [] |
| for passage_id, passage_rank, passage_score in zip(*results): |
| top_k_ids_after_append.append(passage_id) |
|
|
| print(f"Top results after appending back the top passage: {top_k_ids_after_append}") |
|
|
| if ( |
| top_k_ids[1:] == top_k_ids_after_append[1:] |
| and top_k_ids_after_append[0] == new_pids[0] |
| ): |
| print("REAPPEND SUCCEEDED") |
| else: |
| print("REAPPEND FAILED!!!") |
| all_tests_passed = False |
|
|
| |
| new_pids.extend( |
| index_updater.add( |
| [passage_removed, passage_removed, passage_removed, passage_removed] |
| ) |
| ) |
|
|
| |
| |
| results = searcher.search(question, k=k) |
| top_k_ids_after_append = [] |
| for passage_id, passage_rank, passage_score in zip(*results): |
| top_k_ids_after_append.append(passage_id) |
|
|
| print( |
| f"Top results after appending 4 more copies of the top passage: {top_k_ids_after_append}" |
| ) |
|
|
| if set(top_k_ids_after_append) == set( |
| new_pids |
| ): |
| print("REAPPEND 4 more SUCCEEDED") |
| else: |
| print("REAPPEND 4 more FAILED!!!") |
| all_tests_passed = False |
|
|
| |
|
|
| index_updater.persist_to_disk() |
|
|
| config = ColBERTConfig( |
| root=experiment_dir, |
| experiment=experiment, |
| ) |
| searcher = Searcher( |
| index=experiment, |
| config=config, |
| ) |
| results = searcher.search(question, k=k) |
| top_k_ids_reload = [] |
| for passage_id, passage_rank, passage_score in zip(*results): |
| top_k_ids_reload.append(passage_id) |
|
|
| |
|
|
| print( |
| f"Top results after appending 4 more copies of the top passage and reloading: {top_k_ids_reload}" |
| ) |
|
|
| if set(top_k_ids_reload) == set( |
| new_pids |
| ): |
| print("RELOAD SUCCEEDED") |
| else: |
| print("RELOAD FAILED!!!") |
| all_tests_passed = False |
|
|
| if all_tests_passed: |
| print("ALL TESTS PASSED") |
| else: |
| print("SOME TESTS FAILED!!!") |
|
|
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser(description="Start end-to-end test.") |
| parser.add_argument( |
| "--checkpoint", type=str, required=True, help="Model checkpoint" |
| ) |
| parser.add_argument( |
| "--collection", type=str, required=True, help="Path to collection" |
| ) |
| parser.add_argument( |
| "--expdir", type=str, required=True, help="Experiment directory" |
| ) |
| args = parser.parse_args() |
| main(args) |
|
|