mirror of
https://github.com/huggingface/transformers.git
synced 2025-07-15 10:38:23 +06:00
106 lines
4.2 KiB
Python
106 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import logging
|
|
from tqdm import trange
|
|
|
|
import torch
|
|
import torch.nn.functional as F
|
|
import numpy as np
|
|
|
|
from pytorch_pretrained_bert import GPT2LMHeadModel, GPT2Tokenizer
|
|
|
|
logging.basicConfig(format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s',
|
|
datefmt = '%m/%d/%Y %H:%M:%S',
|
|
level = logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def top_k_logits(logits, k):
|
|
if k == 0:
|
|
return logits
|
|
values, _ = torch.topk(logits, k)
|
|
min_values = values[:, -1]
|
|
return torch.where(logits < min_values, torch.ones_like(logits, dtype=logits.dtype) * -1e10, logits)
|
|
|
|
def sample_sequence(model, length, start_token=None, batch_size=None, context=None, temperature=1, top_k=0, device='cuda', sample=True):
|
|
if start_token is None:
|
|
assert context is not None, 'Specify exactly one of start_token and context!'
|
|
context = torch.tensor(context, device=device, dtype=torch.long).unsqueeze(0).repeat(batch_size, 1)
|
|
else:
|
|
assert context is None, 'Specify exactly one of start_token and context!'
|
|
context = torch.full((batch_size, 1), start_token, device=device, dtype=torch.long)
|
|
prev = context
|
|
output = context
|
|
past = None
|
|
with torch.no_grad():
|
|
for i in trange(length):
|
|
logits, past = model(prev, past=past)
|
|
logits = logits[:, -1, :] / temperature
|
|
logits = top_k_logits(logits, k=top_k)
|
|
log_probs = F.softmax(logits, dim=-1)
|
|
if sample:
|
|
prev = torch.multinomial(log_probs, num_samples=1)
|
|
else:
|
|
_, prev = torch.topk(log_probs, k=1, dim=-1)
|
|
output = torch.cat((output, prev), dim=1)
|
|
return output
|
|
|
|
def run_model():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--model_name_or_path', type=str, default='gpt2', help='pretrained model name or path to local checkpoint')
|
|
parser.add_argument("--seed", type=int, default=0)
|
|
parser.add_argument("--nsamples", type=int, default=1)
|
|
parser.add_argument("--batch_size", type=int, default=-1)
|
|
parser.add_argument("--length", type=int, default=-1)
|
|
parser.add_argument("--temperature", type=int, default=1)
|
|
parser.add_argument("--top_k", type=int, default=0)
|
|
parser.add_argument('--unconditional', action='store_true', help='If true, unconditional generation.')
|
|
args = parser.parse_args()
|
|
print(args)
|
|
|
|
if args.batch_size == -1:
|
|
args.batch_size = 1
|
|
assert args.nsamples % args.batch_size == 0
|
|
|
|
np.random.seed(args.seed)
|
|
torch.random.manual_seed(args.seed)
|
|
torch.cuda.manual_seed(args.seed)
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
enc = GPT2Tokenizer.from_pretrained(args.model_name_or_path)
|
|
model = GPT2LMHeadModel.from_pretrained(args.model_name_or_path)
|
|
model.to(device)
|
|
model.eval()
|
|
|
|
if args.length == -1:
|
|
args.length = model.config.n_ctx // 2
|
|
elif args.length > model.config.n_ctx:
|
|
raise ValueError("Can't get samples longer than window size: %s" % model.config.n_ctx)
|
|
|
|
while not args.unconditional:
|
|
if not args.unconditional:
|
|
raw_text = input("Model prompt >>> ")
|
|
while not raw_text:
|
|
print('Prompt should not be empty!')
|
|
raw_text = input("Model prompt >>> ")
|
|
context_tokens = enc.encode(raw_text)
|
|
generated = 0
|
|
for _ in range(args.nsamples // args.batch_size):
|
|
out = sample_sequence(
|
|
model=model, length=args.length,
|
|
context=context_tokens if not args.unconditional else None,
|
|
start_token=enc.encoder['<|endoftext|>'] if args.unconditional else None,
|
|
batch_size=args.batch_size,
|
|
temperature=args.temperature, top_k=args.top_k, device=device
|
|
)
|
|
out = out[:, len(context_tokens):].tolist()
|
|
for i in range(args.batch_size):
|
|
generated += 1
|
|
text = enc.decode(out[i])
|
|
print("=" * 40 + " SAMPLE " + str(generated) + " " + "=" * 40)
|
|
print(text)
|
|
print("=" * 80)
|
|
|
|
if __name__ == '__main__':
|
|
run_model()
|