gpt3.py 3.48 KB
Newer Older
Jason Phang's avatar
gpt3  
Jason Phang committed
1
2
import os
import transformers
Jason Phang's avatar
lib  
Jason Phang committed
3
4
from lm_eval.base import LM
from lm_eval import utils
Leo Gao's avatar
Leo Gao committed
5
from tqdm import tqdm
Leo Gao's avatar
Leo Gao committed
6
import time
Leo Gao's avatar
Leo Gao committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


def get_result(response, ctxlen):
    is_greedy = True
    logprobs = response["logprobs"]["token_logprobs"]
    continuation_logprobs = sum(logprobs[ctxlen:])

    for i in range(ctxlen, len(response["logprobs"]["tokens"])):
        token = response["logprobs"]["tokens"][i]
        top_tokens = response["logprobs"]["top_logprobs"][i]
        top_token = max(top_tokens.keys(), key=lambda x: top_tokens[x])
        if top_token != token:
            is_greedy = False
            break
    
    return continuation_logprobs, is_greedy
Jason Phang's avatar
gpt3  
Jason Phang committed
23
24


Leo Gao's avatar
Leo Gao committed
25
26
27
28
29
30
31
32
33
34
35
36
def oa_completion(**kwargs):
    import openai

    backoff_time = 3
    while True:
        try:
            return openai.Completion.create(**kwargs)
        except openai.error.OpenAIError:
            time.sleep(backoff_time)
            backoff_time *= 1.5


Jason Phang's avatar
gpt3  
Jason Phang committed
37
class GPT3LM(LM):
Jason Phang's avatar
Jason Phang committed
38
39

    MAX_LENGTH = 2048
Leo Gao's avatar
Leo Gao committed
40
    REQ_CHUNK_SIZE = 64
Leo Gao's avatar
Leo Gao committed
41
    MAX_GEN_TOKS = 256
Jason Phang's avatar
Jason Phang committed
42
43
44
45
46
47
48
49
50
51

    def __init__(self, engine, truncate=False):
        """

        :param engine: str
            OpenAI API engine (e.g. davinci)
        :param truncate: bool
            Truncate input if too long (if False and input is too long, throw error)
        """
        import openai
Jason Phang's avatar
gpt3  
Jason Phang committed
52
        self.engine = engine
53
        self.tokenizer = transformers.GPT2TokenizerFast.from_pretrained('gpt2')
Leo Gao's avatar
Leo Gao committed
54
55
56

        # to make the annoying "Using pad_token, but it is not set yet." error go away
        self.tokenizer.pad_token = "<|endoftext|>"
Jason Phang's avatar
Jason Phang committed
57
58
        self.truncate = truncate

Jason Phang's avatar
gpt3  
Jason Phang committed
59
60
61
62
        # Read from environment variable OPENAI_API_SECRET_KEY
        openai.api_key = os.environ["OPENAI_API_SECRET_KEY"]

    @classmethod
Jason Phang's avatar
lib  
Jason Phang committed
63
    def create_from_arg_string(cls, arg_string):
Jason Phang's avatar
gpt3  
Jason Phang committed
64
65
66
        args = utils.simple_parse_args_string(arg_string)
        return cls(engine=args.get("engine", "davinci"))

Leo Gao's avatar
Leo Gao committed
67
    def loglikelihood(self, requests):
Leo Gao's avatar
Leo Gao committed
68
        import openai
Leo Gao's avatar
Leo Gao committed
69
70
71
        res = []

        for chunk in tqdm(list(utils.chunks(requests, self.REQ_CHUNK_SIZE))):
Leo Gao's avatar
Leo Gao committed
72
73
74
75
76
77
78
79
80
81
82
            inps = []
            ctxlens = []
            for context, continuation in chunk:
                context_enc = self.tokenizer.encode(context)
                continuation_enc = self.tokenizer.encode(continuation)
                inp = (context_enc + continuation_enc)[-self.MAX_LENGTH:]
                ctxlen = len(context_enc) - max(0, len(context_enc) + len(continuation_enc) - self.MAX_LENGTH)

                inps.append(inp)
                ctxlens.append(ctxlen)

Leo Gao's avatar
Leo Gao committed
83
            response = oa_completion(
Leo Gao's avatar
Leo Gao committed
84
85
86
87
88
89
90
91
92
93
94
95
96
                engine=self.engine,
                prompt=inps,
                echo=True,
                max_tokens=0, temperature=0.,
                logprobs=10,
            )

            for resp, ctxlen in zip(response.choices, ctxlens):
                res.append(get_result(resp, ctxlen))
            
        return res

    def greedy_until(self, requests):
Leo Gao's avatar
Leo Gao committed
97
98
99
100
101
102
103
104
        import openai
        res = []

        for context, until in tqdm(requests):
            context_enc = self.tokenizer.encode(context)
            inp = context_enc[-(self.MAX_LENGTH - self.MAX_GEN_TOKS):]
            ctxlen = len(context_enc) - max(0, len(context_enc) - (self.MAX_LENGTH - self.MAX_GEN_TOKS))

Leo Gao's avatar
Leo Gao committed
105
            response = oa_completion(
Leo Gao's avatar
Leo Gao committed
106
107
108
109
110
111
112
113
114
115
116
                engine=self.engine,
                prompt=[inp],
                max_tokens=self.MAX_GEN_TOKS, 
                temperature=0.,
                logprobs=10,
            )

            res.append(response.choices[0]['text'])
        
        return res