Home

Awesome

Needle In A Haystack - Pressure Testing LLMs

A simple 'needle in a haystack' analysis to test in-context retrieval ability of long context LLMs.

Supported model providers: OpenAI, Anthropic, Cohere

Get the behind the scenes on the overview video.

GPT-4-128 Context Testing

The Test

  1. Place a random fact or statement (the 'needle') in the middle of a long context window (the 'haystack')
  2. Ask the model to retrieve this statement
  3. Iterate over various document depths (where the needle is placed) and context lengths to measure performance

This is the code that backed this OpenAI and Anthropic analysis.

The results from the original tests are in /original_results. The script has upgraded a lot since those test were ran so the data formats may not match your script results.

Getting Started

Setup Virtual Environment

We recommend setting up a virtual environment to isolate Python dependencies, ensuring project-specific packages without conflicting with system-wide installations.

python3 -m venv venv
source venv/bin/activate

Environment Variables

Install Package

Install the package from PyPi:

pip install needlehaystack

Run Test

Start using the package by calling the entry point needlehaystack.run_test from command line.

You can then run the analysis on OpenAI, Anthropic, or Cohere models with the following command line arguments:

Additionally, LLMNeedleHaystackTester parameters can also be passed as command line arguments, except model_to_test and evaluator.

Here are some example use cases.

Following command runs the test for openai model gpt-3.5-turbo-0125 for a single context length of 2000 and single document depth of 50%.

needlehaystack.run_test --provider openai --model_name "gpt-3.5-turbo-0125" --document_depth_percents "[50]" --context_lengths "[2000]"

Following command runs the test for anthropic model claude-2.1 for a single context length of 2000 and single document depth of 50%.

needlehaystack.run_test --provider anthropic --model_name "claude-2.1" --document_depth_percents "[50]" --context_lengths "[2000]"

Following command runs the test for cohere model command-r for a single context length of 2000 and single document depth of 50%.

needlehaystack.run_test --provider cohere --model_name "command-r" --document_depth_percents "[50]" --context_lengths "[2000]"

For Contributors

  1. Fork and clone the repository.
  2. Create and activate the virtual environment as described above.
  3. Set the environment variables as described above.
  4. Install the package in editable mode by running the following command from repository root:
pip install -e .

The package needlehaystack is available for import in your test cases. Develop, make changes and test locally.

LLMNeedleHaystackTester parameters:

LLMMultiNeedleHaystackTester parameters:

Other Parameters:

Results Visualization

LLMNeedleInHaystackVisualization.ipynb holds the code to make the pivot table visualization. The pivot table was then transferred to Google Slides for custom annotations and formatting. See the google slides version. See an overview of how this viz was created here.

OpenAI's GPT-4-128K (Run 11/8/2023)

<img src="img/GPT_4_testing.png" alt="GPT-4-128 Context Testing" width="800"/>

Anthropic's Claude 2.1 (Run 11/21/2023)

<img src="img/Claude_2_1_testing.png" alt="GPT-4-128 Context Testing" width="800"/>

Multi Needle Evaluator

To enable multi-needle insertion into our context, use --multi_needle True.

This inserts the first needle at the specified depth_percent, then evenly distributes subsequent needles through the remaining context after this depth.

For even spacing, it calculates the depth_percent_interval as:

depth_percent_interval = (100 - depth_percent) / len(self.needles)

So, the first needle is placed at a depth percent of depth_percent, the second at depth_percent + depth_percent_interval, the third at depth_percent + 2 * depth_percent_interval, and so on.

Following example shows the depth percents for the case of 10 needles and depth_percent of 40%.

depth_percent_interval = (100 - 40) / 10 = 6

Needle 1: 40
Needle 2: 40 + 6 = 46
Needle 3: 40 + 2 * 6 = 52
Needle 4: 40 + 3 * 6 = 58
Needle 5: 40 + 4 * 6 = 64
Needle 6: 40 + 5 * 6 = 70
Needle 7: 40 + 6 * 6 = 76
Needle 8: 40 + 7 * 6 = 82
Needle 9: 40 + 8 * 6 = 88
Needle 10: 40 + 9 * 6 = 94

LangSmith Evaluator

You can use LangSmith to orchestrate evals and store results.

(1) Sign up for LangSmith (2) Set env variables for LangSmith as specified in the setup. (3) In the Datasets + Testing tab, use + Dataset to create a new dataset, call it multi-needle-eval-sf to start. (4) Populate the dataset with a test question:

question: What are the 5 best things to do in San Franscisco?
answer: "The 5 best things to do in San Francisco are: 1) Go to Dolores Park. 2) Eat at Tony's Pizza Napoletana. 3) Visit Alcatraz. 4) Hike up Twin Peaks. 5) Bike across the Golden Gate Bridge"

Screenshot 2024-03-05 at 4 54 15 PM (5) Run with --evaluator langsmith and --eval_set multi-needle-eval-sf to run against our recently created eval set.

Let's see all these working together on a new dataset, multi-needle-eval-pizza.

Here is the multi-needle-eval-pizza eval set, which has a question and reference answer. You can also and resulting runs: https://smith.langchain.com/public/74d2af1c-333d-4a73-87bc-a837f8f0f65c/d

Here is the command to run this using multi-needle eval and passing the relevant needles:

needlehaystack.run_test --evaluator langsmith --context_lengths_num_intervals 3 --document_depth_percent_intervals 3 --provider openai --model_name "gpt-4-0125-preview" --multi_needle True --eval_set multi-needle-eval-pizza --needles '["Figs are one of the three most delicious pizza toppings.", "Prosciutto is one of the three most delicious pizza toppings.", "Goat cheese is one of the three most delicious pizza toppings."]'

License

This project is licensed under the MIT License - see the LICENSE file for details. Use of this software requires attribution to the original author and project, as detailed in the license.