<jupyter_start><jupyter_text>Python Notebook training NPI on political viewsThis notebook is also an example on how to use the NPI project to train your own NPI in a way that can affect GPT2's sentiment or emotion. This notebook attempts to train the GPT2 model with NPI to possess a specific political view.  Setup Prerequisite setup for Colab:*   Ensure you selected a runtime with a GPU. You can do that by clicking Runtime -> Change runtime type ->  Hardware Accelerator -> GPU*   After running the setup code in this section, restart the runtime by clicking Runtime -> Restart runtime.After you have done the prerequisite setup, you will not need to rerun this section again. For local machines with CUDA:Run the following code if you do not have the towards-neural-programming-interfaces repo. If you already have the repository, make sure you ran `./install_dependencies.sh` in the repo root.After you done so, skip to the [Post Setup section](post-setup)<jupyter_code>!git clone https://github.com/NancyFulda/towards-neural-programming-interfaces.git
!cd towards-neural-programming-interfaces && ./install_dependencies.sh<jupyter_output><empty_output><jupyter_text>Post setup***Note: You will need to restart the runtime on Colab to continue***Click on Runtime -> Restart Runtime to do so.<jupyter_code># Download the NewB news source dataset if you haven't yet.
# This is for the Politics dataset.
!git clone https://github.com/JerryWei03/NewB.git
# For dev purposes, enable autoreload of modules
%load_ext autoreload
import pandas as pd
import torch

%autoreload

# Constructing training dataset
from npi.dataset import NPIDatasetConstructor, NPIDatasetLoader

# Models
from npi.models import NPITrainingModels

# Training NPI
from npi.training import NPIStyleTrainer, NPITrainer

# Configuration
from npi.config import NPIConfig<jupyter_output><empty_output><jupyter_text>Note that each step in training an NPI is conditioned on the variable toggles, so you can disable certain steps to not redo them again when running the whole notebook.<jupyter_code># Toggle steps
construct = True
train_class = True
test_class = True
train_npi = True<jupyter_output><empty_output><jupyter_text>Below is where an NPIConfig object is defined. It holds configuration for the NPI that you can use for the different NPI training steps. Notice that it is injected intothe NPITrainingModels class. That class will load the necessary models using the configuration defined in NPIConfig.<jupyter_code>model_layers = [5, 11]

device = torch.device(f"cuda:0")
config = NPIConfig(
    device, gpt_model="gpt2", perturbation_indices=model_layers, npi_name="politics"
)

# Initialize models for training and testing
models = NPITrainingModels(
    config,
)<jupyter_output><empty_output><jupyter_text>Create Dataset Get Data from NewB GitHub repoNote that this step will be different depending on the data you would want to train the NPI on. About Construct DataThe key here is to give `construct_data.construct_dataset` a tuple of `(input_text, label)`.Currently, `construct_data.construct_dataset` will generate up to the `NPIConfig.num_iters` times of text from GPT based on the input text, and labels those activations with the label you assigned to the input text. This is assuming the text outputted by GPT2 was relevant to our input text. Limitations* The labels that are currently supported is just `1` and `0`. *You need to label the type of output you want the GPT2 with NPI model to create with `0`.** Currently, you will need to manually stop the dataset generation if you want to end it before it goes through your input* If you don't have a dataset with labels, you will need to create that manually.* Despite your configurations for which GPT layers to modify by the NPI, this step will generate the data from all GPT layers<jupyter_code>if construct:
    with open("./NewB/train_orig.txt", "r", newline="") as f:
        data = pd.read_csv(f, delimiter="\t", names=["view", "text"])
        data["view"] = data["view"].replace(
            to_replace={0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1}
        )
        data = data[data.view != 5]
        data = data.sample(frac=1)
        data_iter = zip(data["text"], data["view"])
        construct_data = NPIDatasetConstructor(config)
        construct_data.construct_dataset(data_iter, 4000) # Only creating 4000 training data points 
        # TODO: setting the limit of training data points is a WIP. You can manually stop the cell to stop the dataset generation.<jupyter_output><empty_output><jupyter_text>Train classifier from Dataset<jupyter_code>model_loader = NPITrainingModels(config)
dataset_loader = NPIDatasetLoader(config, target="style")
style_trainer = NPIStyleTrainer(config, class_lr=1e-5)
classifier = None
if train_class:
    classifier = style_trainer.train_classifier(
        model_loader,
        dataset_loader,
        num_epochs=5,
        #continue_epoch=4,  # Set epoch of classifier to load to continue training.
    )<jupyter_output><empty_output><jupyter_text>Test Classifier<jupyter_code>_, test_loader, _, _ = dataset_loader.load_train_and_test_dataloaders()

classifier = model_loader.load_style_classifier() if not classifier else classifier
# When output=True, it will log the following in models/npi_models/style_classifier_output.log:
#   (generated text from the dataset)
#   truth={target_label} actual={model_output}
style_trainer.test_model(test_loader, classifier, torch.nn.BCELoss(), output=True)<jupyter_output><empty_output><jupyter_text>Training NPI<jupyter_code>num_epochs = 6
split_ratio = 0.25
batch_size = 5
headstart = 0  # set at 0 for debugging

if train_npi:
    trainer = NPITrainer(config, batch_size=batch_size, headstart=headstart)
    dataset_loader = NPIDatasetLoader(config, split_ratio=split_ratio)
    trainer.train_adversarial_npi(models, num_epochs, dataset_loader)<jupyter_output><empty_output><jupyter_text>Test NPI Using the model loader, you can directly generate NPI text.<jupyter_code>text = "Trump today was found"
print(f"\nOriginal GPT2 output: '{text}'\n{models.gpt2_generate_text(text)}")

print(f"\nNPI GPT2 output: '{text}'\n{models.npi_generate_text(text)}")<jupyter_output>Model: GPT2 with NPI: 100it [00:05, 18.87it/s]
{'fraction_non_alphanumeric': 0.07786819850007978, 'fraction_numerical': 0.011329184617839477, 'mean_word_length': 5.169291338582677, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 41, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '353675', 'license': 'Apache-2.0', 'n_tokens_mistral': 1937, 'n_tokens_neox': 1839, 'n_words': 695, 'path': 'notebooks/politics/politics_colab.ipynb', 'repo_name': 'NancyFulda/towards-neural-programming-interfaces', 'size': '6267'}