Welcome! This internal repository contains all the assets for the CRFM/Mercury benchmarking project. There are two related parts:
- Proxy (
src/proxy
): provides a unified way to access major language models. - Benchmarking (see
src/benchmark
): evaluates such language models.
To install any dependencies (into venv
):
./pre-commit.sh
We provide a single unified entry point into accessing large language models (e.g., GPT-3, Jurassic). This provides both a web interface and a REST API.
To use the web interface, go to https://crfm-models.stanford.edu.
To use the REST API, see demo.py.
Create prod_env/credentials.conf
to contain the API keys for any language
models you have access to.
openaiApiKey: ...
ai21ApiKey: ...
To start a local server (go to http://localhost:1959
to try it out):
venv/bin/proxy-server
The production version of the proxy is running on crfm-models.stanford.edu
;
you need to get permission to get ssh access.
This is done, but just for the record:
laptop:$ ssh crfm-models.stanford.edu
crfm-models:$ cd /home
crfm-models:$ git clone [email protected]:stanford-crfm/benchmarking
crfm-models:$ cd benchmarking
crfm-models:$ mkdir prod_env
crfm-models:$ echo '{"api_key": "crfm"}' > prod_env/accounts.jsonl
laptop:$ rsync -arvz prod_env/credentials.conf crfm-models.stanford.edu:/home/benchmarking/prod_env
We use Google's Perspective API to calculate the toxicity of completions.
To send requests to PerspectiveAPI, we need to generate an API key from GCP. Follow the
Get Started guide
to request the service and the Enable the API guide
to generate the API key. Once you have a valid API key, add an entry to credentials.conf
:
perspectiveApiKey: <Generated API key>
By default, Perspective API allows only 1 query per second. Fill out this form to increase the request quota.
The current API key
we are using in production was created with the hai-gcp-models
account and allows 100 queries per second.
The API key expires on 4/15/2022.
The SSL certificate, CSR and private key for crfm-models.stanford.edu is stored at /home/ssl
.
The current SSL certificate expires on 12/30/2022.
To renew the SSL certificate, follow these steps:
-
Fill out this form:
- Log on with your SUNet ID. You must be an admin in order to submit a request.
- For
Server Name
, putcrfm-models.stanford.edu
. - For
Server type
, selectOTHER
. - For
Contact group/mailman address
, enter your Stanford email address. - Under
Copy and paste your CSR
, paste the content of/home/ssl/public.csr
. - Leave the optional fields blank and click
Submit
. - You should receive your certificate by email within 2 business days.
-
Once you receive the SSL cert, concatenate the contents of
X509 Certificate only, Base64 encoded
with the contents ofX509 Intermediates/root only Reverse, Base64 encoded
and place it at path/home/ssl/crfm-models.crt
.crfm-models.crt
should look something like this:-----BEGIN CERTIFICATE----- (Your Primary SSL certificate: .crt) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your Intermediate certificate: reversed.crt) -----END CERTIFICATE-----
-
Restart the server.
-
Open the website in a browser and verify the connection is secure.
If, for whatever reason, the private key or CSR is misplaced, generate new ones by running:
sudo openssl req -new -nodes -newkey rsa:2048 -keyout private.key -out public.csr
and fill out the form:
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:Stanford
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Stanford University
Organizational Unit Name (eg, section) []:CRFM
Common Name (e.g. server FQDN or YOUR name) []:crfm-models.stanford.edu
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Then, follow the steps above to request for a new SSL certificate.
Update the code:
laptop:$ ssh crfm-models.stanford.edu
crfm-models:$ cd /home/benchmarking
crfm-models:$ git pull
crfm-models:$ ./pre-commit.sh
If everything looks okay:
# Switch into the screen session
crfm-models:$ gos bench
# Hit ctrl-c to kill the existing process
sudo venv/bin/proxy-server -p 443 --ssl-key-file /home/ssl/private.key --ssl-cert-file /home/ssl/crfm-models.crt
Double check that the website still works.
Here's a birds-eye view of how the benchmarking process interacts with the main
classes (see benchmark
):
-
A
Scenario
(given by aScenarioSpec
) specifies a task and a data distribution. It specifies a set ofInstance
s, where eachInstance
has an input (e.g., question) and a set ofReference
outputs (e.g., multiple choice answers). -
A
DataPreprocessor
takes in aScenario
and produces a list ofInstance
s EachInstance
is given a unique ID. The set ofInstance
s is augmented according toDataAugmenterSpec
. -
An
Adapter
(given by anAdaptationSpec
) takes a list ofInstance
s and adapts it to a set ofRequest
s to the API (e.g., the model, temperature, number of in-context training examples). Formally, the output is aScenarioState
containing a set ofRequestState
s, where eachRequestState
consists of aRequest
and any metadata used to track the role of thisRequest
(e.g., the relevantInstance
andReference
). -
An
Executor
(given by anExecutionSpec
) executes eachRequest
in theRequestState
to produce aRequestResult
for each one; everything is encapsulated in aScenarioState
. -
A
Metric
(given by aMetricSpec
) takes aScenarioState
containingRequestResults
s and produces a set ofStat
s (e.g., accuracy, accuracy@5, toxicity, bias, etc.). -
A
Runner
is the top-level controller that runs the above steps and is driven by a set ofRunSpec
s.
There are three types of classes:
- Specifications (e.g.,
AdapterSpec
,ExecutionSpec
,RunSpec
): specified manually by the user. Note thatScenario
andMetric
are subclassed, so they are constructed byObjectSpec
, which specifies the subclass name and a free-form dictionary of arguments. - States (e.g.,
Instance
,ScenarioState
,Request
,RequestResult
): these are automatically generated and can be serialized. - Controllers (e.g.,
Scenario
,Adapter
,Executor
,Metric
,Runner
): these have the bulk of the code and should not be serialized.
To apply data augmentation, create a DataAugmenterSpec
with a list of
PerturbationSpec
s and pass it into RunSpec
. The following is an
example:
data_augmenter_spec = DataAugmenterSpec(
perturbation_specs=[
PerturbationSpec(
class_name="benchmark.augmentations.perturbation.ExtraSpacePerturbation",
args={"num_spaces": 5},
)
],
should_perturb_references=False,
should_augment_train_instances=False,
should_include_original_train=False,
should_augment_eval_instances=True,
should_include_original_eval=True,
)
run_spec = RunSpec(
...
data_augmenter_spec=data_augmenter_spec
)
In the example above, the DataPreprocessor
will augment the set of evaluation instances by perturbing
the original set of instances with the ExtraSpacePerturbation
, where spaces in the text are
replaced with num_spaces
number of spaces.
We currently only support applying a single perturbation to an instance instead of chaining multiple perturbations and applying it onto a single instance.
To add a new perturbation to the framework, create a new file at src/benchmark/augmentations
with the name
<Name of perturbation>_perturbation.py
e.g., typo_perturbation.py
. Inside the file, create a new class
(name it <Name of the perturbation>Perturbation
e.g., TypoPerturbation
)
that extends the abstract class Perturbation
and implement the perturb
method which
takes in text and outputs the perturbed text.
Add your new perturbation to src/benchmark/__init__.py
.
Add a test for the new perturbation in test_perturbation.py
.
Examples of running the benchmark:
venv/bin/benchmark-run
venv/bin/benchmark-run -r mmlu:subject=philosophy
venv/bin/benchmark-run -r synthetic_reasoning_natural:difficulty=easy
venv/bin/benchmark-run -r twitter_aae:demographic=aa
venv/bin/benchmark-run -r copyright:pilot_study=true
venv/bin/benchmark-run -r disinformation:capability=reiteration
venv/bin/benchmark-run -r wiki:k=2,subject=P31
venv/bin/benchmark-run -r code:dataset=APPS
venv/bin/benchmark-run -r the_pile:subset=OpenSubtitles
venv/bin/benchmark-run -r wiki:subject=P31
venv/bin/benchmark-run -r raft:subset=ade_corpus_v2
venv/bin/benchmark-run -r natural_qa:mode=closedbook
venv/bin/benchmark-run -r quac
venv/bin/benchmark-run -r wikitext_103
venv/bin/benchmark-run -r blimp:phenomenon=irregular_forms
venv/bin/benchmark-run -r news_qa
venv/bin/benchmark-run -r imdb
venv/bin/benchmark-run -r imdb_contrast_sets
You can also run the benchmark using a local proxy, in which case you have to first start a local server (see instructions above for more details).
To estimate token usage without making any requests, append the --dry-run
option:
venv/bin/benchmark-run -r <RunSpec to estimate token usage> --dry-run
For example, running venv/bin/benchmark-run -r real_toxicity_prompts --dry-run
outputs:
Stats {
openai/davinci_estimated_number_of_tokens[min=505.000, mean=514.957, max=536.000, sum=514957.000 (1000)]
}
where sum
indicates the estimated total number of tokens used for the specific RunSpec
.
For the OpenAI models, we use a GPT-2 Tokenizer to estimate the token usage. The tokenizer will be downloaded and cached when running a dry run.
- Running all the
RunSpec
s can take a long time, so use SCDT:ssh scdt
. - Create a screen session:
screen -S benchmarking
. - Go to the source code directory:
cd /u/scr/nlp/crfm/benchmarking/benchmarking
. We have 700 GB of disk space total on/u/scr/nlp/crfm
. - Pull the latest changes:
git pull
. - Activate the Conda environment:
conda activate crfm_benchmarking
- Run
pip install -e .
if there are new dependencies to install.
- Run
- Run the
benchmark-present
command e.g.,benchmark-present --max-eval-instances 10 --conf src/benchmark/presentation/run_specs.conf
. - Exit the screen session:
ctrl+ad
. - To check on the screen session:
screen -r benchmarking
.
- Run
venv/bin/benchmark-present --output-path src/proxy/static/benchmark_output
. - Visit the benchmarking status page.
To contribute to this project, install the dependencies and git hook scripts:
./pre-commit.sh && pre-commit install
To run all unit tests:
python -m pytest
Append -vv
to output the full diff and results:
python -m pytest -vv
To run a specific file, simply specify the path:
python -m pytest <path/to/file> -vv