-
Notifications
You must be signed in to change notification settings - Fork 0
/
gptlm.py
49 lines (45 loc) · 1.81 KB
/
gptlm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import math
import torch
import numpy as np
class GPT2LM:
def __init__(self, use_tf=False, device=None, little=False):
import logging
logging.getLogger("transformers").setLevel(logging.ERROR)
import os
os.environ["TOKENIZERS_PARALLELISM"] = "false"
import transformers
self.use_tf = use_tf
self.tokenizer = transformers.GPT2TokenizerFast.from_pretrained("gpt2-large")
if use_tf:
self.lm = transformers.TFGPT2LMHeadModel.from_pretrained("gpt2")
else:
self.lm = transformers.GPT2LMHeadModel.from_pretrained("gpt2-large", from_tf=False)
self.lm.to(device)
def __call__(self, sent):
"""
:param str sent: A sentence.
:return: Fluency (ppl).
:rtype: float
"""
if self.use_tf:
import tensorflow as tf
ipt = self.tokenizer(sent, return_tensors="tf", verbose=False)
ret = self.lm(ipt)[0]
loss = 0
for i in range(ret.shape[0]):
it = ret[i]
it = it - tf.reduce_max(it, axis=1)[:, tf.newaxis]
it = it - tf.math.log(tf.reduce_sum(tf.exp(it), axis=1))[:, tf.newaxis]
it = tf.gather_nd(it, list(zip(range(it.shape[0] - 1), ipt.input_ids[i].numpy().tolist()[1:])))
loss += tf.reduce_mean(it)
break
return math.exp(-loss)
else:
ipt = self.tokenizer(sent, return_tensors="pt", verbose=False, )
try:
ppl = math.exp(self.lm(input_ids=ipt['input_ids'].cuda(),
attention_mask=ipt['attention_mask'].cuda(),
labels=ipt.input_ids.cuda())[0])
except RuntimeError:
ppl = np.nan
return ppl