CoolFace
Apppublic

zachlopez/sample_1

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
app.py908 linesDownload Raw Back to root
1#! /usr/bin/env python32# coding=utf-83# Copyright 2018 The Uber AI Team Authors.4#5# Licensed under the Apache License, Version 2.0 (the "License");6# you may not use this file except in compliance with the License.7# You may obtain a copy of the License at8#9#     http://www.apache.org/licenses/LICENSE-2.010#11# Unless required by applicable law or agreed to in writing, software12# distributed under the License is distributed on an "AS IS" BASIS,13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14# See the License for the specific language governing permissions and15# limitations under the License.16# temperature17"""18Example command with bag of words:19python examples/run_pplm.py -B space --cond_text "The president" --length 100 --gamma 1.5 --num_iterations 3 --num_samples 10 --stepsize 0.01 --window_length 5 --kl_scale 0.01 --gm_scale 0.9520 21Example command with discriminator:22python examples/run_pplm.py -D sentiment --class_label 3 --cond_text "The lake" --length 10 --gamma 1.0 --num_iterations 30 --num_samples 10 --stepsize 0.01 --kl_scale 0.01 --gm_scale 0.9523"""24 25import gradio as gr26import argparse27import json28from operator import add29from typing import List, Optional, Tuple, Union30from random import choice, randint31import numpy as np32import torch33import torch.nn.functional as F34from torch.autograd import Variable35from tqdm import trange36from transformers import GPT2Tokenizer37from transformers.file_utils import cached_path38from transformers.modeling_gpt2 import GPT2LMHeadModel39from pplm_classification_head import ClassificationHead40 41PPLM_BOW = 142PPLM_DISCRIM = 243PPLM_BOW_DISCRIM = 344SMALL_CONST = 1e-1545BIG_CONST = 1e1046 47QUIET = 048REGULAR = 149VERBOSE = 250VERY_VERBOSE = 351VERBOSITY_LEVELS = {52    'quiet': QUIET,53    'regular': REGULAR,54    'verbose': VERBOSE,55    'very_verbose': VERY_VERBOSE,56}57 58BAG_OF_WORDS_ARCHIVE_MAP = {59    'legal': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/legal.txt",60    'military': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/military.txt",61    'monsters': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/monsters.txt",62    'politics': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/politics.txt",63    'positive_words': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/positive_words.txt",64    'religion': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/religion.txt",65    'science': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/science.txt",66    'space': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/space.txt",67    'technology': "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/bow/technology.txt",68}69 70DISCRIMINATOR_MODELS_PARAMS = {71    "clickbait": {72        "url": "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/discriminators/clickbait_classifier_head.pt",73        "class_size": 2,74        "embed_size": 1024,75        "class_vocab": {"non_clickbait": 0, "clickbait": 1},76        "default_class": 1,77        "pretrained_model": "gpt2-medium",78    },79    "sentiment": {80        "url": "https://s3.amazonaws.com/models.huggingface.co/bert/pplm/discriminators/SST_classifier_head.pt",81        "class_size": 5,82        "embed_size": 1024,83        "class_vocab": {"very_positive": 2, "very_negative": 3},84        "default_class": 3,85        "pretrained_model": "gpt2-medium",86    },87    "3_PerSoothe": {88        "path": "/content/drive/Shareddrives/COS_IW04_ZL/COSIW04/Discriminators/3_class_opt_lowlr_medgpt/3_PerSoothe_classifier_head_epoch_10.pt",89        "class_size": 3, 90        "embed_size": 1024, 91        "class_vocab": {"soothes": 0, "neutral": 1, "worsens": 2}, 92        "default_class": 2,93        "pretrained_model": "microsoft/DialoGPT-medium", 94    },95    "3_PerSoothe_eot": {96        "path": "/content/drive/Shareddrives/COS_IW04_ZL/COSIW04/Discriminators/3_class_opt_eot_lowlr_medgpt/3_PerSoothe_classifier_head_epoch_10.pt",97        "class_size": 3, 98        "embed_size": 1024, 99        "class_vocab": {"soothes": 0, "neutral": 1, "worsens": 2}, 100        "default_class": 2,101        "pretrained_model": "microsoft/DialoGPT-medium", 102    },103    "3_PerSoothe_lrg": {104        "class_size": 3, 105        "embed_size": 1280, 106        "class_vocab": {"soothes": 0, "neutral": 1, "worsens": 2}, 107        "default_class": 2,108        "pretrained_model": "microsoft/DialoGPT-large", 109    },110    "3_PerSoothe_med": {111        "class_size": 3, 112        "embed_size": 1024, 113        "class_vocab": {"soothes": 0, "neutral": 1, "worsens": 2}, 114        "default_class": 2,115        "pretrained_model": "microsoft/DialoGPT-medium", 116    },117}118 119 120def to_var(x, requires_grad=False, volatile=False, device='cuda'):121    if torch.cuda.is_available() and device == 'cuda':122        x = x.cuda()123    elif device != 'cuda':124        x = x.to(device)125    return Variable(x, requires_grad=requires_grad, volatile=volatile)126 127 128def top_k_filter(logits, k, probs=False):129    """130    Masks everything but the k top entries as -infinity (1e10).131    Used to mask logits such that e^-infinity -> 0 won't contribute to the132    sum of the denominator.133    """134    if k == 0:135        return logits136    else:137        values = torch.topk(logits, k)[0]138        batch_mins = values[:, -1].view(-1, 1).expand_as(logits)139        if probs:140            return torch.where(logits < batch_mins,141                               torch.ones_like(logits) * 0.0, logits)142        return torch.where(logits < batch_mins,143                           torch.ones_like(logits) * -BIG_CONST,144                           logits)145 146 147def perturb_past(148        past,149        model,150        last,151        unpert_past =None,152        unpert_logits=None,153        accumulated_hidden=None,154        grad_norms=None,155        stepsize=0.01,156        one_hot_bows_vectors=None,157        classifier=None,158        class_label=None,159        loss_type=0,160        num_iterations=3,161        horizon_length=1,162        window_length=0,163        decay=False,164        gamma=1.5,165        kl_scale=0.01,166        device='cuda',167        verbosity_level=REGULAR168):169    # Generate inital perturbed past170    grad_accumulator = [171        (np.zeros(p.shape).astype("float32"))172        for p in past173    ]174 175    if accumulated_hidden is None:176        accumulated_hidden = 0177 178    if decay:179        decay_mask = torch.arange(180            0.,181            1.0 + SMALL_CONST,182            1.0 / (window_length)183        )[1:]184    else:185        decay_mask = 1.0186 187    # TODO fix this comment (SUMANTH)188    # Generate a mask is gradient perturbated is based on a past window189    _, _, _, curr_length, _ = past[0].shape190 191    if curr_length > window_length and window_length > 0:192        ones_key_val_shape = (193                tuple(past[0].shape[:-2])194                + tuple([window_length])195                + tuple(past[0].shape[-1:])196        )197 198        zeros_key_val_shape = (199                tuple(past[0].shape[:-2])200                + tuple([curr_length - window_length])201                + tuple(past[0].shape[-1:])202        )203 204        ones_mask = torch.ones(ones_key_val_shape)205        ones_mask = decay_mask * ones_mask.permute(0, 1, 2, 4, 3)206        ones_mask = ones_mask.permute(0, 1, 2, 4, 3)207 208        window_mask = torch.cat(209            (ones_mask, torch.zeros(zeros_key_val_shape)),210            dim=-2211        ).to(device)212    else:213        window_mask = torch.ones_like(past[0]).to(device)214 215    # accumulate perturbations for num_iterations216    loss_per_iter = []217    new_accumulated_hidden = None218    for i in range(num_iterations):219        if verbosity_level >= VERBOSE:220            print("Iteration ", i + 1)221        curr_perturbation = [222            to_var(torch.from_numpy(p_), requires_grad=True, device=device)223            for p_ in grad_accumulator224        ]225 226        # Compute hidden using perturbed past227        perturbed_past = list(map(add, past, curr_perturbation))228        _, _, _, curr_length, _ = curr_perturbation[0].shape229        all_logits, _, all_hidden = model(last, past_key_values=perturbed_past)230        hidden = all_hidden[-1]231        new_accumulated_hidden = accumulated_hidden + torch.sum(232            hidden,233            dim=1234        ).detach()235        # TODO: Check the layer-norm consistency of this with trained discriminator (Sumanth)236        logits = all_logits[:, -1, :]237        probs = F.softmax(logits, dim=-1)238 239        loss = 0.0240        loss_list = []241        if loss_type == PPLM_BOW or loss_type == PPLM_BOW_DISCRIM:242            for one_hot_bow in one_hot_bows_vectors:243                bow_logits = torch.mm(probs, torch.t(one_hot_bow))244                bow_loss = -torch.log(torch.sum(bow_logits))245                loss += bow_loss246                loss_list.append(bow_loss)247            if verbosity_level >= VERY_VERBOSE:248                print(" pplm_bow_loss:", loss.data.cpu().numpy())249 250        if loss_type == PPLM_DISCRIM or loss_type == PPLM_BOW_DISCRIM:251            ce_loss = torch.nn.CrossEntropyLoss()252            # TODO why we need to do this assignment and not just using unpert_past? (Sumanth)253            curr_unpert_past = unpert_past254            curr_probs = torch.unsqueeze(probs, dim=1)255            wte = model.resize_token_embeddings()256            for _ in range(horizon_length):257                inputs_embeds = torch.matmul(curr_probs, wte.weight.data)258                _, curr_unpert_past, curr_all_hidden = model(259                    past_key_values=curr_unpert_past,260                    inputs_embeds=inputs_embeds261                )262                curr_hidden = curr_all_hidden[-1]263                new_accumulated_hidden = new_accumulated_hidden + torch.sum(264                    curr_hidden, dim=1)265 266            prediction = classifier(new_accumulated_hidden /267                                    (curr_length + 1 + horizon_length))268 269            label = torch.tensor(prediction.shape[0] * [class_label],270                                 device=device,271                                 dtype=torch.long)272            discrim_loss = ce_loss(prediction, label)273            if verbosity_level >= VERY_VERBOSE:274                print(" pplm_discrim_loss:", discrim_loss.data.cpu().numpy())275            loss += discrim_loss276            loss_list.append(discrim_loss)277 278        kl_loss = 0.0279        if kl_scale > 0.0:280            unpert_probs = F.softmax(unpert_logits[:, -1, :], dim=-1)281            unpert_probs = (282                    unpert_probs + SMALL_CONST *283                    (unpert_probs <= SMALL_CONST).float().to(device).detach()284            )285            correction = SMALL_CONST * (probs <= SMALL_CONST).float().to(286                device).detach()287            corrected_probs = probs + correction.detach()288            kl_loss = kl_scale * (289                (corrected_probs * (corrected_probs / unpert_probs).log()).sum()290            )291            if verbosity_level >= VERY_VERBOSE:292                print(' kl_loss', kl_loss.data.cpu().numpy())293            loss += kl_loss294 295        loss_per_iter.append(loss.data.cpu().numpy())296        if verbosity_level >= VERBOSE:297            print(' pplm_loss', (loss - kl_loss).data.cpu().numpy())298 299        # compute gradients300        loss.backward()301 302        # calculate gradient norms303        if grad_norms is not None and loss_type == PPLM_BOW:304            grad_norms = [305                torch.max(grad_norms[index], torch.norm(p_.grad * window_mask))306                for index, p_ in enumerate(curr_perturbation)307            ]308        else:309            grad_norms = [310                (torch.norm(p_.grad * window_mask) + SMALL_CONST)311                for index, p_ in enumerate(curr_perturbation)312            ]313 314        # normalize gradients315        grad = [316            -stepsize *317            (p_.grad * window_mask / grad_norms[318                index] ** gamma).data.cpu().numpy()319            for index, p_ in enumerate(curr_perturbation)320        ]321 322        # accumulate gradient323        grad_accumulator = list(map(add, grad, grad_accumulator))324 325        # reset gradients, just to make sure326        for p_ in curr_perturbation:327            p_.grad.data.zero_()328 329        # removing past from the graph330        new_past = []331        for p_ in past:332            new_past.append(p_.detach())333        past = new_past334 335    # apply the accumulated perturbations to the past336    grad_accumulator = [337        to_var(torch.from_numpy(p_), requires_grad=True, device=device)338        for p_ in grad_accumulator339    ]340    pert_past = list(map(add, past, grad_accumulator))341 342    return pert_past, new_accumulated_hidden, grad_norms, loss_per_iter343 344 345def get_classifier(346        name: Optional[str],347        class_label: Union[str, int],348        device: str,349        verbosity_level: int = REGULAR,350        fp: str = None,351        is_deep: bool= False,352        is_deeper: bool=False,353) -> Tuple[Optional[ClassificationHead], Optional[int]]:354    if name is None:355        return None, None356 357    params = DISCRIMINATOR_MODELS_PARAMS[name]358    classifier = ClassificationHead(359        class_size=params['class_size'],360        embed_size=params['embed_size'],361        is_deep=is_deep,362        is_deeper=is_deeper363    ).to(device)364    if "url" in params:365        resolved_archive_file = cached_path(params["url"])366    elif "path" in params:367        resolved_archive_file = params["path"]368    elif fp != None:369        resolved_archive_file = fp370    else:371        raise ValueError("Either url or path have to be specified "372                         "in the discriminator model parameters")373    classifier.load_state_dict(374        torch.load(resolved_archive_file, map_location=device))375    classifier.eval()376 377    if isinstance(class_label, str):378        if class_label in params["class_vocab"]:379            label_id = params["class_vocab"][class_label]380        else:381            label_id = params["default_class"]382            if verbosity_level >= REGULAR:383                print("class_label {} not in class_vocab".format(class_label))384                print("available values are: {}".format(params["class_vocab"]))385                print("using default class {}".format(label_id))386 387    elif isinstance(class_label, int):388        if class_label in set(params["class_vocab"].values()):389            label_id = class_label390        else:391            label_id = params["default_class"]392            if verbosity_level >= REGULAR:393                print("class_label {} not in class_vocab".format(class_label))394                print("available values are: {}".format(params["class_vocab"]))395                print("using default class {}".format(label_id))396 397    else:398        label_id = params["default_class"]399 400    return classifier, label_id401 402 403def get_bag_of_words_indices(bag_of_words_ids_or_paths: List[str], tokenizer) -> \404        List[List[List[int]]]:405    bow_indices = []406    for id_or_path in bag_of_words_ids_or_paths:407        if id_or_path in BAG_OF_WORDS_ARCHIVE_MAP:408            filepath = cached_path(BAG_OF_WORDS_ARCHIVE_MAP[id_or_path])409        else:410            filepath = id_or_path411        with open(filepath, "r") as f:412            words = f.read().strip().split("\n")413        bow_indices.append(414            [tokenizer.encode(word.strip(),415                              add_prefix_space=True,416                              add_special_tokens=False)417             for word in words])418    return bow_indices419 420 421def build_bows_one_hot_vectors(bow_indices, tokenizer, device='cuda'):422    if bow_indices is None:423        return None424 425    one_hot_bows_vectors = []426    for single_bow in bow_indices:427        single_bow = list(filter(lambda x: len(x) <= 1, single_bow))428        single_bow = torch.tensor(single_bow).to(device)429        num_words = single_bow.shape[0]430        one_hot_bow = torch.zeros(num_words, tokenizer.vocab_size).to(device)431        one_hot_bow.scatter_(1, single_bow, 1)432        one_hot_bows_vectors.append(one_hot_bow)433    return one_hot_bows_vectors434 435 436def full_text_generation(437        model,438        tokenizer,439        context=None,440        num_samples=1,441        device="cuda",442        bag_of_words=None,443        discrim=None,444        class_label=None,445        length=100,446        stepsize=0.02,447        temperature=1.0,448        top_k=10,449        sample=True,450        num_iterations=3,451        grad_length=10000,452        horizon_length=1,453        window_length=0,454        decay=False,455        gamma=1.5,456        gm_scale=0.9,457        kl_scale=0.01,458        verbosity_level=REGULAR,459        fp=None,460        is_deep=False,461        is_deeper=False,462        stop_eot=False,463        **kwargs464):465    classifier, class_id = get_classifier(466        discrim,467        class_label,468        device,469        REGULAR,470        fp,471        is_deep,472        is_deeper473    )474 475    bow_indices = []476    if bag_of_words:477        bow_indices = get_bag_of_words_indices(bag_of_words.split(";"),478                                               tokenizer)479 480    if bag_of_words and classifier:481        loss_type = PPLM_BOW_DISCRIM482        if verbosity_level >= REGULAR:483            print("Both PPLM-BoW and PPLM-Discrim are on. "484                  "This is not optimized.")485 486    elif bag_of_words:487        loss_type = PPLM_BOW488        if verbosity_level >= REGULAR:489            print("Using PPLM-BoW")490 491    elif classifier is not None:492        loss_type = PPLM_DISCRIM493        if verbosity_level >= REGULAR:494            print("Using PPLM-Discrim")495 496    else:497        raise Exception("Specify either a bag of words or a discriminator")498 499    unpert_gen_tok_text, _, _, _ = generate_text_pplm(500        model=model,501        tokenizer=tokenizer,502        context=context,503        device=device,504        length=length,505        sample=sample,506        perturb=False,507        verbosity_level=verbosity_level,508        stop_eot=stop_eot509    )510    if device == 'cuda':511        torch.cuda.empty_cache()512 513    pert_gen_tok_texts = []514    discrim_losses = []515    losses_in_time = []516    perplexities = []517 518    for i in range(num_samples):519        pert_gen_tok_text, discrim_loss, loss_in_time, perplexity = generate_text_pplm(520            model=model,521            tokenizer=tokenizer,522            context=context,523            device=device,524            perturb=True,525            bow_indices=bow_indices,526            classifier=classifier,527            class_label=class_id,528            loss_type=loss_type,529            length=length,530            stepsize=stepsize,531            temperature=temperature,532            top_k=top_k,533            sample=sample,534            num_iterations=num_iterations,535            grad_length=grad_length,536            horizon_length=horizon_length,537            window_length=window_length,538            decay=decay,539            gamma=gamma,540            gm_scale=gm_scale,541            kl_scale=kl_scale,542            verbosity_level=verbosity_level,543            stop_eot=stop_eot544        )545        pert_gen_tok_texts.append(pert_gen_tok_text)546        if classifier is not None:547            discrim_losses.append(discrim_loss.data.cpu().numpy())548        losses_in_time.append(loss_in_time)549        perplexities.append(perplexity)550 551    if device == 'cuda':552        torch.cuda.empty_cache()553 554    return unpert_gen_tok_text, pert_gen_tok_texts, discrim_losses, losses_in_time, perplexities555 556 557def generate_text_pplm(558        model,559        tokenizer,560        context=None,561        past=None,562        device="cuda",563        perturb=True,564        bow_indices=None,565        classifier=None,566        class_label=None,567        loss_type=0,568        length=100,569        stepsize=0.02,570        temperature=1.0,571        top_k=10,572        sample=True,573        num_iterations=3,574        grad_length=10000,575        horizon_length=1,576        window_length=0,577        decay=False,578        gamma=1.5,579        gm_scale=0.9,580        kl_scale=0.01,581        verbosity_level=REGULAR,582        stop_eot=False583):584    output_so_far = None585    if context:586        context_t = torch.tensor(context, device=device, dtype=torch.long)587        while len(context_t.shape) < 2:588            context_t = context_t.unsqueeze(0)589        output_so_far = context_t590 591    # collect one hot vectors for bags of words592    one_hot_bows_vectors = build_bows_one_hot_vectors(bow_indices, tokenizer,593                                                      device)594 595    grad_norms = None596    last = None597    unpert_discrim_loss = 0598    loss_in_time = []599 600    if verbosity_level >= VERBOSE:601        range_func = trange(length, ascii=True)602    else:603        range_func = range(length)604    605    pert_total_prob = 1606    pert_times = 0607    last_reps = torch.ones(50257)608    last_reps = last_reps.to(device)609    for i in range_func:610        # Get past/probs for current output, except for last word611        # Note that GPT takes 2 inputs: past + current_token612        613        # run model forward to obtain unperturbed614        if past is None and output_so_far is not None:615            last = output_so_far[:, -1:]616            if output_so_far.shape[1] > 1:617                _, past, _ = model(output_so_far[:, :-1])618 619        unpert_logits, unpert_past, unpert_all_hidden = model(output_so_far)620        unpert_last_hidden = unpert_all_hidden[-1]621 622        # check if we are abowe grad max length623        if i >= grad_length:624            current_stepsize = stepsize * 0625        else:626            current_stepsize = stepsize627 628        # modify the past if necessary629        if not perturb or num_iterations == 0:630            pert_past = past631 632        else:633            accumulated_hidden = unpert_last_hidden[:, :-1, :]634            accumulated_hidden = torch.sum(accumulated_hidden, dim=1)635 636            if past is not None:637                pert_past, _, grad_norms, loss_this_iter = perturb_past(638                    past,639                    model,640                    last,641                    unpert_past=unpert_past,642                    unpert_logits=unpert_logits,643                    accumulated_hidden=accumulated_hidden,644                    grad_norms=grad_norms,645                    stepsize=current_stepsize,646                    one_hot_bows_vectors=one_hot_bows_vectors,647                    classifier=classifier,648                    class_label=class_label,649                    loss_type=loss_type,650                    num_iterations=num_iterations,651                    horizon_length=horizon_length,652                    window_length=window_length,653                    decay=decay,654                    gamma=gamma,655                    kl_scale=kl_scale,656                    device=device,657                    verbosity_level=verbosity_level658                )659                loss_in_time.append(loss_this_iter)660            else:661                pert_past = past662 663        pert_logits, past, pert_all_hidden = model(last, past_key_values=pert_past)664        pert_logits = pert_logits[:, -1, :] / temperature  # + SMALL_CONST665        pert_probs = F.softmax(pert_logits, dim=-1)666 667        if classifier is not None:668            ce_loss = torch.nn.CrossEntropyLoss()669            prediction = classifier(torch.mean(unpert_last_hidden, dim=1))670            label = torch.tensor([class_label], device=device,671                                 dtype=torch.long)672            unpert_discrim_loss = ce_loss(prediction, label)673            if verbosity_level >= VERBOSE:674                print(675                    "unperturbed discrim loss",676                    unpert_discrim_loss.data.cpu().numpy()677                )678        else:679            unpert_discrim_loss = 0680 681        # Fuse the modified model and original model682        if perturb:683 684            unpert_probs = F.softmax(unpert_logits[:, -1, :], dim=-1)685 686            pert_probs = ((pert_probs ** gm_scale) * (687                    unpert_probs ** (1 - gm_scale)))  # + SMALL_CONST688            if i < 2:689                pert_probs = top_k_filter(pert_probs, k=max(2, top_k), probs=True)  # + SMALL_CONST690                if i == 0: pert_probs[0][50256] = 0691                if i == 1: 692                    tmp = pert_probs[0][50256]693                    pert_probs[0][50256] = 0694                    pert_probs[0][50256] = min(torch.max(pert_probs[0]), tmp)695            else:696                pert_probs = top_k_filter(pert_probs, k=top_k, probs=True)  # + SMALL_CONST697            pert_probs = torch.div(pert_probs, last_reps)698            # rescale699            if torch.sum(pert_probs) <= 1:700                pert_probs = pert_probs / torch.sum(pert_probs)701        else:702            pert_logits = top_k_filter(pert_logits, k=top_k)  # + SMALL_CONST703            pert_probs = F.softmax(pert_logits, dim=-1)704 705        # sample or greedy706        if sample:707            last = torch.multinomial(pert_probs, num_samples=1)708            pert_total_prob = pert_total_prob * pert_probs[0][last[0][0]]709        else:710            _, last = torch.topk(pert_probs, k=1, dim=-1)711        last_reps[last[0][0]] = last_reps[last[0][0]] * 8712        # update context/output_so_far appending the new token713        output_so_far = (714            last if output_so_far is None715            else torch.cat((output_so_far, last), dim=1)716        )717        if verbosity_level >= REGULAR:718            print(tokenizer.decode(output_so_far.tolist()[0]))719        pert_times += 1720        if last[0][0] ==  50256 and stop_eot: 721          break722    perplexity = (1/pert_total_prob)**(1/pert_times)723    return output_so_far, unpert_discrim_loss, loss_in_time, perplexity724 725 726def set_generic_model_params(discrim_weights, discrim_meta):727    if discrim_weights is None:728        raise ValueError('When using a generic discriminator, '729                         'discrim_weights need to be specified')730    if discrim_meta is None:731        raise ValueError('When using a generic discriminator, '732                         'discrim_meta need to be specified')733 734    with open(discrim_meta, 'r') as discrim_meta_file:735        meta = json.load(discrim_meta_file)736    meta['path'] = discrim_weights737    DISCRIMINATOR_MODELS_PARAMS['generic'] = meta738 739 740pretrained_model="microsoft/DialoGPT-large"741cond_text=""742uncond=False743num_samples=1744bag_of_words=None745discrim="3_PerSoothe_lrg"746discrim_weights=None747discrim_meta=None748class_label=0749length=100750stepsize=0.32751temperature=1.3752top_k=2753sample=True754num_iterations=0755grad_length=10000756horizon_length=1757window_length=0758decay=False759gamma=1.0760gm_scale=0.95761kl_scale=0.01762seed=0763no_cuda=False764colorama=False765verbosity="quiet"766fp="./paper_code/discrim_models/persoothe_classifier.pt"767model_fp=None768calc_perplexity=False769is_deep=False770is_deeper=True771stop_eot=True772 773# set Random seed774torch.manual_seed(seed)775np.random.seed(seed)776 777# set verbosiry778verbosity_level = VERBOSITY_LEVELS.get(verbosity.lower(), REGULAR)779 780# set the device781device = "cuda" if torch.cuda.is_available() and not no_cuda else "cpu"782 783if discrim == 'generic':784    set_generic_model_params(discrim_weights, discrim_meta)785 786if discrim is not None:787    discriminator_pretrained_model = DISCRIMINATOR_MODELS_PARAMS[discrim][788        "pretrained_model"789    ]790    if pretrained_model != discriminator_pretrained_model:791        pretrained_model = discriminator_pretrained_model792        if verbosity_level >= REGULAR:793            print("discrim = {}, pretrained_model set "794            "to discriminator's = {}".format(discrim, pretrained_model))795 796# load pretrained model797model = GPT2LMHeadModel.from_pretrained(798    pretrained_model,799    output_hidden_states=True800)801if model_fp != None and model_fp != "": 802    model.load_state_dict(torch.load(model_fp, map_location=device))803model.to(device)804model.eval()805 806# load tokenizer807tokenizer = GPT2Tokenizer.from_pretrained(pretrained_model)808 809# Freeze GPT-2 weights810for param in model.parameters():811    param.requires_grad = False812 813starters = ["How are you feeling and why?", "Tell me about your day", "What would you like to talk about?"]814eot_token = "<|endoftext|>"815 816def get_reply(response, username = None, histories = {}, in_stepsize = 0.32, in_horizon_length = 1, in_num_iterations = 0, in_top_k = 2):817    if username == None or username == "": return "<div class='chatbot'>Enter a username</div>", histories818    stepsize = in_stepsize819    horizon_length = int(in_horizon_length)820    num_iterations = int(in_num_iterations)821    top_k = int(in_top_k)822    if response.endswith(("bye", "Bye", "bye.", "Bye.", "bye!", "Bye!","Hello", "Hi", "hello")):823        starter = choice(starters)824        histories[username] = starter+"<|endoftext|>"825        html = "<div class='chatbot'> Chatbot restarted"826        html += "<div class='msg user'>"+starter+"</div>"827        html += "</div>"828        return html, histories829    history = histories.get(username, None)830    convo_hist = (history if history != None else "How are you?<|endoftext|>") + response + eot_token831    # figure out conditioning text832    tokenized_cond_text = tokenizer.encode(833            eot_token + convo_hist,834            add_special_tokens=False835    )836    # generate perturbed texts837 838    # full_text_generation returns:839    # unpert_gen_tok_text, pert_gen_tok_texts, discrim_losses, losses_in_time840    _, pert_gen_tok_texts, _, _, _ = full_text_generation(841        model=model,842        tokenizer=tokenizer,843        context=tokenized_cond_text,844        device=device,845        num_samples=1,846        bag_of_words=bag_of_words,847        discrim=discrim,848        class_label=class_label,849        length=length,850        stepsize=stepsize,851        temperature=temperature,852        top_k=top_k,853        sample=sample,854        num_iterations=num_iterations,855        grad_length=grad_length,856        horizon_length=horizon_length,857        window_length=window_length,858        decay=decay,859        gamma=gamma,860        gm_scale=gm_scale,861        kl_scale=kl_scale,862        verbosity_level=verbosity_level,863        fp=fp,864        is_deep=is_deep,865        is_deeper=is_deeper,866        stop_eot=stop_eot867    )868 869    # iterate through the perturbed texts870    for i, pert_gen_tok_text in enumerate(pert_gen_tok_texts):871        try:872            pert_gen_text = tokenizer.decode(pert_gen_tok_text.tolist()[0])873            convo_hist_split = pert_gen_text.split(eot_token)874            html = "<div class='chatbot'>"875            for m, msg in enumerate(convo_hist_split[1:-1]):876                cls = "user" if m%2 == 0 else "bot"877                html += "<div class='msg {}'> {}</div>".format(cls, msg)878            html += "</div>"879 880            if len(convo_hist_split) > 4: convo_hist_split = convo_hist_split[-4:]881            convo_hist = eot_token.join(convo_hist_split)882 883        except:884            starter = choice(starters)885            histories[username] = starter+"<|endoftext|>"886            html = "<div class='chatbot'> Chatbot restarted"887            html += "<div class='msg user'>"+starter+"</div>"888            html += "</div>"889            return html, histories890    histories[username] = convo_hist891    return html, histories892 893css = """894.chatbox {display:flex;flex-direction:column}895.msg {padding:4px;margin-bottom:4px;border-radius:4px;width:80%}896.msg.user {background-color:cornflowerblue;color:white}897.msg.bot {background-color:lightgray;align-self:self-end}898.footer {display:none !important}899"""900 901gr.Interface(fn=get_reply,902             theme="default",903             inputs=[gr.inputs.Textbox(placeholder="How are you?"), 904                    gr.inputs.Textbox(label="Username"),905                    "state"],906             outputs=["html", "state"],907             css=css).launch(debug=True, enable_queue=True, share=True) 908