Selective Context

repository·main·Indexed 19 days ago

https://github.com/liyucheng09/selective_context

A tool for compressing LLM prompts and contexts using self-information to maximize the utility of fixed context lengths. It allows models to process more content by filtering less informative text at the sentence, phrase, or token level. The package includes the SelectiveContext API, a Streamlit web interface, and utilities for reproducing experimental results across datasets like Arxiv, News, and Conversation.

Tokens
5.3K
Snippets
20
Records
22
Agent score
65%

What's inside selective-context

  1. Reproduce experiments from the paper

    main

    To reproduce the experimental results, download the dataset dumps and run the main.py script with the required arguments: dataset path, number of articles, and the Hugging Face model name/path.

    # 1. Download and unzip datasets
    wget https://github.com/liyucheng09/Selective_Context/releases/download/v0.1.0rc1/datasets_dumps.zip
    unzip datasets_dumps.zip
    
    # 2. Run experiments
    python main.py datasets_dumps/arxiv datasets_dumps/news datasets_dump/conversation <output_path_to_save_results> <num_articles> <HF_model_name_or_path>
  2. Install selective-context

    main

    Install the package via PyPI and download the required spaCy language models. For English, use en_core_web_sm. If you are processing Chinese text, you must also download zh_core_web_sm.

    pip install selective-context
    python -m spacy download en_core_web_sm
    # For Chinese support:
    python -m spacy download zh_core_web_sm
  3. Configure masking granularity levels

    main

    When calling SelectiveContext, you can choose how the context is reduced via the reduce_level parameter. This determines the unit of text that gets replaced by a mask token if its self-information is below the threshold.

    • 'sent': Masks entire sentences. If keep_leading_word is enabled (internal setting), it may preserve a few words at the start of the sentence.
    • 'phrase': Masks noun phrases (using spacy's noun chunking).
    • 'token': Masks individual tokens.
  4. Configure SelectiveContext reduction levels

    main

    The reduce_level parameter in the SelectiveContext.__call__ method determines the granularity at which information is filtered. The algorithm calculates self-information and masks units that fall below a certain percentile threshold.

    • 'sent': Filters entire sentences. Masked sentences are replaced by a <deleted> token.
    • 'phrase': Filters at the noun-phrase level (using spacy for English or direct processing for Chinese). Masked phrases are replaced by an empty string or specific mask token.
    • 'token': Filters at the individual token level. Masked tokens are replaced by an empty string.
  5. Perform task-wise and data-wise performance analysis

    main

    To understand how Selective Context performs on specific subsets of your experiments, use the following patterns:

    Task-wise Analysis: Groups results by the task type (e.g., summarisation, qa, reconstruction, continue_conversation). This is useful for seeing if context reduction affects certain types of reasoning more than others.

    Data-wise Analysis: Groups results by the dataset source (e.g., news mapped to BBC, arxiv, or conversation mapped to ShareGPT). This helps identify if the method is sensitive to the domain of the text.

    Both patterns return a Pandas DataFrame indexed by the grouping dimension and the Ratio (context reduction ratio).

    def task_wise(context_type):
        # Returns DataFrame indexed by ['Task', 'Ratio']
        ...
    
    def data_wise(context_type):
        # Returns DataFrame indexed by ['Data', 'Ratio']
        ...
  6. Analyze and visualize Selective Context results

    main

    The show_results.ipynb notebook provides a framework for processing, aggregating, and visualizing experimental results from the Selective Context project. It uses a read_results function to load pickled metric files and aggregate them into Pandas DataFrames.

    Key capabilities include:

    • Aggregation by Context Type: Compare different context reduction methods (e.g., self-info-phrase, Random-phrase, no2-phrase) across various tasks and mask ratios.
    • Task-wise Analysis: View performance metrics (BLEU, ROUGE, BERTScore) grouped by specific tasks like summarisation, qa, or conversation.
    • Data-wise Analysis: Compare performance across different datasets like news (BBC) or arxiv.
    • Visualization: Generate line plots using matplotlib to show how performance metrics change as the context reduction ratio increases.
    import pandas as pd
    import matplotlib.pyplot as plt
    
    # Example: Visualizing BLEU scores across different ratios
    # Assuming df2 is Selective Context results and df is Random baseline
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 4), dpi=120)
    
    df2.plot(y='bleu', x='Ratio', ax=axes[0], marker='^', label='Selective Context')
    df.plot(y='bleu', x='Ratio', ax=axes[0], marker='+', label='Random')
    axes[0].set_title('BLEU')
    # ... additional plotting logic
  7. Convert parsed articles to a HuggingFace Dataset

    main

    After initializing a parser instance, you can iterate through manager.articles to extract conversation data. This data can be converted into a pandas DataFrame and subsequently into a HuggingFace Dataset for sharing or further processing.

    Steps:

    1. Extract entry_id and context from each article.
    2. Create a list of dictionaries.
    3. Convert to a pandas DataFrame.
    4. Convert to a HuggingFace Dataset.
    # 1. Extract data
    covs = [{'id': article.entry_id, 'chat': article.context} for article in manager.articles]
    
    # 2. Convert to DataFrame
    import pandas as pd
    df = pd.DataFrame.from_dict(covs, orient='columns')
    
    # 3. Convert to HuggingFace Dataset
    from datasets import Dataset
    ds = Dataset.from_pandas(df)
    
    # 4. (Optional) Push to HuggingFace Hub
    ds.push_to_hub('liyucheng/sharegpt-500')
  8. Run Selective Context evaluations via main.py

    main

    The main.py script serves as the entry point for running experiments across different datasets, task types, and masking strategies. It orchestrates the generation of contexts, the generation of answers using LLMs, and the evaluation of those answers.

    CLI Usage

    The script expects six positional arguments:

    1. arxiv_path: Path to the Arxiv dataset.
    2. news_path: Path to the News dataset.
    3. conversation_path: Path to the Conversation dataset.
    4. save_to_path: Directory where logs and results will be saved.
    5. num_articles: Number of articles to process (integer).
    6. model_name: The name of the LLM to use (e.g., gpt-3.5-turbo).

    Execution Workflow

    1. Context Generation: Uses dataset_managers (like ArxivContextManager, NewsContextManager, or ConversationContextManager) to create original and masked contexts based on mask_types (e.g., self-info, Random, no) and mask_ratios.
    2. Task Execution: Uses task_managers to perform specific tasks such as summarisation, qa, reconstruction, or continue_conversation.
    3. Evaluation: If do_eval is set to True, an Evaluator is used to calculate metrics like bleu, meteor, rouge, bertscore, or bleurt.
    4. Persistence: Results and performance metrics are saved as pickle files.
    python main.py /path/to/arxiv /path/to/news /path/to/conv /path/to/save 100 gpt-3.5-turbo
  9. Use the SelectiveContext API to compress text

    main

    The SelectiveContext class allows you to compress prompts and context to increase the amount of content an LLM can process. You initialize the class with a model_type (e.g., 'gpt2') and a lang (e.g., 'en'), then call the instance on your text. It returns the compressed context and the reduced content.

    from selective_context import SelectiveContext
    
    # Initialize with a base model and language
    sc = SelectiveContext(model_type='gpt2', lang='en')
    
    # Compress text (returns compressed context and the reduced content)
    context, reduced_content = sc(text)
    
    # Compress text with a specific reduction ratio
    context, reduced_content = sc(text, reduce_ratio=0.5)
  10. Load serialized context managers from pickle files

    main

    Pre-processed context managers or experiment results can be loaded using the pickle module. This is useful for resuming work or inspecting metrics from previous runs.

    import pickle
    
    # Loading a NewsContextManager
    with open('/path/to/NewsContextManager_sent.pkl', 'rb') as f:
        news = pickle.load(f)
    
    # Accessing article sections
    section_text = news.articles[0].sections[0]
    
    # Loading experiment metrics
    with open('/path/to/answer_summarisation_arxiv_0.35.pkl', 'rb') as f:
        d = pickle.load(f)
    print(d.metrics)
  11. Initialize the parser class for context management

    main

    The parser class (which inherits from ConversationContextManager) is used to load and manage conversation contexts. It allows for fine-grained control over how text is tokenized, masked, and processed for Selective Context experiments.

    Key parameters include:

    • path (str): The directory path containing the conversation data.
    • mask_ratio (float): The ratio of content to be masked (default: 0.2).
    • keep_leading_word (bool): Whether to keep leading words of a segment (default: True).
    • num_lead_words (int): Number of leading words to preserve (default: 3).
    • ppl_threshold (float): Perplexity threshold for selection.
    • tokenizer: A HuggingFace tokenizer (defaults to GPT2Tokenizer if not provided).
    • sent_mask_token (str): The token used to represent masked sentences (default: "<...some content omitted.>").
    • phrase_mask_token (str): The token used to represent masked phrases.
    • num_articles (int): Number of articles to load (default: 2000).
    • lang (str): Language of the text (default: "en").
    from context_manager import ConversationContextManager
    
    class parser(ConversationContextManager):
        def __init__(
            self,
            path : str,
            mask_ratio = 0.2, 
            keep_leading_word = True,
            num_lead_words = 3,
            ppl_threshold = None,
            tokenizer = None,
            compute_self_info = True,
            sent_mask_token = "<...some content omitted.>",
            phrase_mask_token = "",
            num_articles = 2000,
            lang = "en",
        ):
            # ... initialization logic ...