JavRedstone's picture
download
raw
5.05 kB
""" Length generalization: testing how well RoPE and PoPE generalize to
extrapolated sequence lengths compared to that used for training.
This script loads a ckpt and runs inference on sequences of greater length
and plots perplexity vs sequence length. """
import os
from contextlib import nullcontext
import numpy as np
import torch
from data.pg19.prepare import PG19DataLoader
from model import GPTConfig, GPT
init_from = 'resume' # either 'resume' (from an out_dir) or a gpt2 variant (e.g. 'gpt2-xl')
base_dir = ''
ckpt_dir = 'final-owt-ckpts/' # ignored if init_from is not 'resume'
ckpt_fname = 'gpt2-124M-rope-ckpt.pt' # ignored if init_from is not 'resume'
dataset = 'pg19' # 'openwebtext', 'pg19'
split = 'val' # for pg19 we use the test split
# model
n_layer = 12
n_head = 12
n_embd = 768
block_size = 1024
batch_size = 1
dropout = 0.0 # for pretraining 0 is good, for finetuning try 0.1+
norm_type = 'rmsnorm' # 'layernorm' or 'rmsnorm'
pos_type = 'rope' # 'rope' or 'pope'
base_freq = 10000 # base frequency for rotary positional encoding
rotate_fraction = 1.0
thetab_init = 'zero'
bias = False # do we use bias inside LayerNorm and Linear layers?
complex_flash = False
eval_iters = 1500 # how many iterations to run the evaluation loop
# sampling
num_samples = 1 # number of samples to draw
max_new_tokens = 500 # number of tokens generated in each sample
temperature = 0.8 # 1.0 = no change, < 1.0 = less random, > 1.0 = more random, in predictions
top_k = 200 # retain only the top_k most likely tokens, clamp others to have 0 probability
seed = 1337
device = 'cuda' # examples: 'cpu', 'cuda', 'cuda:0', 'cuda:1', etc.
dtype = 'bfloat16' if torch.cuda.is_available() and torch.cuda.is_bf16_supported() else 'float16' # 'float32' or 'bfloat16' or 'float16'
compile = True # use PyTorch 2.0 to compile the model to be faster
exec(open('configurator.py').read()) # overrides from command line or config file
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cuda.matmul.allow_tf32 = True # allow tf32 on matmul
torch.backends.cudnn.allow_tf32 = True # allow tf32 on cudnn
device_type = 'cuda' if 'cuda' in device else 'cpu' # for later use in torch.autocast
ptdtype = {'float32': torch.float32, 'bfloat16': torch.bfloat16, 'float16': torch.float16}[dtype]
ctx = nullcontext() if device_type == 'cpu' else torch.amp.autocast(device_type=device_type, dtype=ptdtype)
data_dir = os.path.join(base_dir, 'data', dataset)
# init from a model saved in a specific directory
def load_ckpt():
ckpt_path = os.path.join(os.path.join(base_dir, ckpt_dir, ckpt_fname))
print(f"Loading checkpoint from {ckpt_path}...")
checkpoint = torch.load(ckpt_path, map_location=device)
# updating block size in model args
gptconf = GPTConfig(**checkpoint['model_args'])
model = GPT(gptconf)
state_dict = checkpoint['model']
unwanted_prefix = '_orig_mod.'
for k,v in list(state_dict.items()):
if k.startswith(unwanted_prefix):
state_dict[k[len(unwanted_prefix):]] = state_dict.pop(k)
model.load_state_dict(state_dict, strict=False)
return model
def get_batch(split, chunk_size):
target_mask = None
data = np.memmap(os.path.join(data_dir, split + '.bin'), dtype=np.uint16, mode='r')
ix = torch.randint(len(data) - chunk_size, (batch_size,))
x = torch.stack([torch.from_numpy((data[i:i+chunk_size]).astype(np.int64)) for i in ix])
y = torch.stack([torch.from_numpy((data[i+1:i+1+chunk_size]).astype(np.int64)) for i in ix])
x, y = x.pin_memory().to(device, non_blocking=True), y.pin_memory().to(device, non_blocking=True)
return x, y, target_mask
extra_lengths = np.arange(block_size, 10*block_size+1, block_size)
loss_vs_length = {}
# load model
model = load_ckpt()
model.eval()
model.to(device)
if compile:
model = torch.compile(model)
# run evals at various lengths
for l in extra_lengths:
print(f"Eval with block size {l}...")
# init dataloader for PG-19 dataset
ds = PG19DataLoader(
seq_len=l+1,
batch_size=batch_size,
streaming=False,
max_books=None,
num_workers=0,
shuffle=False,
pin_memory=True
)
ds_itr = iter(ds)
if dataset == 'pg19':
eval_iters = len(ds_itr) # eval over full test split of PG-19
losses = torch.zeros(eval_iters)
# run inference over dataset
for k in range(eval_iters):
if dataset == 'openwebtext':
x, y, target_mask = get_batch(split, l)
elif dataset == 'pg19':
batch = next(ds_itr)
x = batch['input_ids'].to(device, non_blocking=True)
y = x.clone()[:, 1:]
x = x[:, :-1]
with torch.no_grad():
logits, loss = model(x, y, target_mask=None)
losses[k] = loss.item()
loss_vs_length[l] = losses.mean().item()
print(f"Done with block size {l}.")
if not os.path.exists("length_gen"):
os.makedirs("length_gen")
torch.save(loss_vs_length, f'length_gen/{ckpt_fname[:-8]}-loss-vs-length.pt')

Xet Storage Details

Size:
5.05 kB
·
Xet hash:
8f875d2dc4cbe357b89930f47b5e4e3a07baf58bb66f7ee1b27f7ef55ef3895b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.