This software project accompanies the paper Self-Conditioning Pre-Trained Language Models.
The requirements are listed in frozen_requirements.txt. The code has been tested using Python 3.8 on MacOS and Linux Ubuntu 18.04. Run the following for installation:
cd <path_to_this_project> python3 -m venv env # make sure Python3 >= 3.6 source env/bin/activate pip install -U pip wheel
pip install -r frozen_requirements.txt
python -c "import nltk; nltk.download('punkt')"Using the "not slow" marker will avoid downloading models from the transformers repository.
pytest -m "not slow"To test the full pipeline:
pytest
We provide instructions to read responses from a model given a dataset, to compute expertise results per concept and to aggregate results.
The models are fetched from the HuggingFace Transformers repository.
We currently support [gpt2, gpt-medium, gpt2-large, gpt2-xl].
A small dataset with 1 concept (football) is provided in assets/football for model GPT2-Medium. It contains a file concept_list.csv with the concepts in the dataset,
as well as the actual data inside a folder called sense (since the concepts are of the WordNet sense type, see paper).
The data for each concept is provided as a json file, with positive and negative sentences.
If other concepts were to be added, of a different type, we would save them in a different folder, with the appropriate name.
Run the following script to collect responses from a model. If you have a GPU, this step will run much faster than on CPU.
Choose the model version with --model-name-or-path, for example --model-name-or-path gpt-medium.
python scripts/compute_responses.py \ --model-name-or-path gpt2-medium \ --data-path assets/football \ --responses-path /tmp/path_to_save_responses \ --device cuda
The script above assumes a file
concept_list.csvinside the dataset path. If we want to run the script in specific concepts, pass argument--conceptswith comma separated concepts and specifying the type. For example:--concepts sense/football-1_04_00__,[some_other_concept],...
The responses will be saved inside path_to_save_responses/gpt2-medium/sense/[concept]/responses.
The following script will compute the expertise per unit for each concept. The expertise is defined as the Average Precision (AP) achieved by a unit when its responses are considered prediction scores for the concept sentences.
python scripts/compute_expertise.py \ --root-dir /tmp/path_to_save_responses \ --model-name gpt2-medium \ --concepts assets/football/concept_list.csv
The expertise results are saved as a CSV file in path_to_save_responses/gpt2-medium/sense/[concept]/expertise.
Column ap contains the expertise measured for each model unit and column on_p50 contains the median response of each unit to the positive sentences (Sec 4.2 in paper).
In this step, the above computed expertise is used to generate sentences conditioned on a concept. We provide a script for open ended generation of sentences: scripts/generate_seq.py. It has several parameters to control the decoding strategy, sequence length, expertise related, etc. See --help for details.
Here we give a simple example that generates sentences with concept football for which we obtained the expertise in steps 1.x:
python scripts/generate_seq.py \ --model-name-or-path gpt2-medium \ --expertise my_results/gpt2-medium/sense/football-1_04_00__/expertise/expertise.csv \ # Generate sentences of 20 tokens --length 20 \ # The initial context passed to the model --prompt "Once upon a time" \ # Generate 10 sentences with random seeds ranging from 0 -> 9 --seed 0 10 \ # Final softmax temperature --temperature 1.0 \ # Expert units are sorted according to AP --metric ap \ # And experts are forced using the median expected value (named on_p50) --forcing on_p50 \ # Condition the top 50 expert units --num-units 50 \ # Just show the results, otherwise would save as a csv --no-save
NOTE: First of all, the expertise for concepts woman and man should be computed using steps 1.x and the datasets in assets/gender_bias.
We provide a script that distributes the generation across multiple GPUs (if available) to speed up the experimentation (scripts/generate_batch.py).
The following example will obtain the generated sentences used in the paper.
python scripts/generate_batch.py \ --concept some_path/gpt2-medium/sense/woman-1_18_00__/expertise/expertise.csv \ --device cuda \ --prompts occupations \ --method ours \ --folder generated
The generated sentences will be stored in files generated/gen_sentences_[concept]_[context].csv (one file per concept per context).
We provide a patch to run FUDGE and
obtain generated sentences compatible with our repository.
To run FUDGE we must first clone the code and apply the patch git-patches/fudge.patch:
git clone https://github.com/yangkevin2/naacl-2021-fudge-controlled-generation.git fudge cd fudge git checkout fbedf820c306c5b3cbf684dc414b2464fc603222 # Apply patch git am $SELFCOND/git-patches/fudge.patch # Create a new virtualenv, since PPLM uses a frozen version of transformers virtualenv env_fudge --python=python3.6 . env_fudge/bin/activate pip install -r requirements.txt
Then, use script run_batch.py with the desired arguments. In the patch, we provide the BoW and prompts used in the paper in the directory topic_data.
.
Note that scripts/generate_batch.py also allows running PPLM-BoW.
To run PPLM-BoW we must first clone the code and apply the patch git-patches/pplm.patch.
git clone https://github.com/uber-research/PPLM.git cd PPLM git checkout e236b8989322128360182d29a79944627957ad47 # Apply patch git am $SELFCOND/git-patches/pplm.patch # Create a new virtualenv, since PPLM uses a frozen version of transformers virtualenv env_pplm --python=python3.6 . env_pplm/bin/activate pip install -r requirements.txt
Then, use the argument --method pplm-bow when calling scripts/generate_batch.py.
The following step will aggregate results and obtain the probabilities of specific words appearing after the prompt.
For example, in the example we compute p(he,his | do(woman, k)) and store it in a file p_he_woman.csv.
python scripts/compute_frequency.py # All the files with sentences to consider. --sentences-df "some_path/generated/gen_sentences_woman_*.csv" # Number of characters to consider after the prompt. --num-chars 5 # Method can be selfcond, fudge or pplm --method selfcond --out-file results/selfcond/p_he_woman.csv --words "he;his"
In the paper, we do this step for words he;his and she;her, and for all sentences generated for man and woman, obtaining:
p_he_woman.csvp_she_woman.csvp_he_man.csvp_she_man.csv
Additionally, in our paper we report the probabilities of generating words woman;women and man:men when conditioning on woman or man respecitvely. These files should be saved as:
p_woman_woman.csvp_man_man.csv
NOTE: In order to be able to run step 3.4, save the csv files in
results/[method]as in the example.
We also provide a script to compute the perplexity of generated sentences after generation. As explained in the paper, for that we use a different model family, in this case openai-gpt.
python scripts/compute_perplexity.py --model-name-or-path openai-gpt --sentences-df some_path/generated/gen_sentences_man*.csv --device cuda # Method can be selfcond, fudge or pplm --method selfcond
The results will be saved in a file with the same name as --sentences-df but ending with _ppl.csv instead.
We have an additional script that aggregates the perplexity computed above. Example of usage:
python scripts/aggregate_perplexities.py --ppl-woman some_path/generated/gen_sentences_woman*ppl.csv --ppl-man some_path/generated/gen_sentences_man*ppl.csv # Method can be selfcond, fudge or pplm --method selfcond --out-dir some_path/results
The aggregated perplexities will be saved as pl_woman.csv and ppl_man.csv in results/[method].
Run the following script, that will compute the Self-BLEU score for all the generated sentences passed as --sentences-df.
To speed up the computation (at the expense of a higher variance in the score) one can reduce both --num-sample and --num-reps.
python scripts/compute_selfbleu.py --sentences-df some_path/generated/gen_sentences_*.csv # Method can be selfcond, fudge or pplm --method selfcond --out-dir some_path/results # Number of sentences randomly sampled to compute the score --num-sample 100 # Number of repetitions performed, the reported score will be the average --num-reps 1000 --ngram 3 4
The Self-BLEU scores will be saved in selfbleu_woman.csv and selfbleu_man.csv in results/[method].
The script all_plots.py will produce all the figures in the paper.
It assumes all the results in csv format in a single folder. In the steps above we used results as our main results folder.
All figures will be saved in the directory specified by -o.
Example of usage:
python scripts/all_plots.py -i results -o figures
If you need dark figures, set the variable
DARK_PLOTS=Truein the script.
@article{suau2022selfcond, title={Self-Conditioning Pre-Trained Language Models}, author={Suau, Xavier and Zappella, Luca and Apostoloff, Nicholas}, journal={International Conference on Machine Learning}, year={2022} }
Xavier Suau Cuadros (xsuaucuadros@apple.com)
Luca Zappella (lzappella@apple.com)
Nick Apostoloff (napostoloff@apple.com)