| from model import TransformerConfig, TransformerLanguageModel
|
| from tokenizer import load_tokenizer
|
| import torch
|
| from torch.utils.data import DataLoader
|
| from dataset_loader import MultiSourceDatasetV2
|
| import random
|
| from tqdm import tqdm
|
|
|
|
|
| config = TransformerConfig(
|
| 50304,
|
| 1024,
|
| 768,
|
| 12,
|
| 12,
|
| 0.0,
|
| True
|
| )
|
|
|
|
|
|
|
| batch_size = 8
|
| max_iters = 150000
|
| gradient_accumulation_steps = 5
|
| eval_interval = 100
|
| save_interval = 500
|
| learning_rate = 1e-4
|
| device = 'cuda:0'
|
|
|
|
|
| model = TransformerLanguageModel(config)
|
| model = model.to(device)
|
|
|
| ckpt_id = 43000
|
| checkpoint = f"checkpoints/new/{ckpt_id}.pt"
|
| model.load_state_dict(torch.load(checkpoint))
|
|
|
|
|
| tokenizer = load_tokenizer("tokenizer.model")
|
|
|
|
|
| recipe_files = [
|
| [f"data/enwiki/enwiki-{page}.jsonl" for page in range(6400)],
|
| [f"data/fineweb/fineweb-{page}.jsonl" for page in range(14850)],
|
| [f"data/zhwiki/zhwiki-{page}.jsonl" for page in range(1350)],
|
| [f"data/zhihu/zhihu-{page}.jsonl" for page in range(975)],
|
| [f"data/allnovels-split/ans-{page}.jsonl" for page in range(1330)]
|
| ]
|
| probs = [
|
| 0.2,
|
| 0.3,
|
| 0.2,
|
| 0.1,
|
| 0.2
|
| ]
|
|
|
|
|
| ds = MultiSourceDatasetV2(recipe_files, probs)
|
| loader = DataLoader(ds, batch_size)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| def get_input_ids(text_batch, eos_token_id=50303, block_size=config.block_size):
|
| texts = text_batch["text"]
|
| ids = [tokenizer.encode(text) + [eos_token_id] for text in texts]
|
| for i in range(len(ids)):
|
| if len(ids[i]) > block_size+1:
|
| start = random.randint(0,len(ids[i])-100)
|
| ids[i] = ids[i][start:start+block_size+1]
|
| max_len = max([len(item) for item in ids])
|
| ids = [item + [eos_token_id] * (max_len - len(item)) for item in ids]
|
| ids = torch.tensor(ids, dtype=torch.int64)
|
| return ids[:,:-1],ids[:,1:]
|
|
|
|
|
| optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate)
|
| scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, 1000, 2, 5e-7)
|
|
|
|
|
| @torch.no_grad()
|
| def gen_text(text):
|
| model.eval()
|
| ids = torch.tensor(tokenizer.encode(text)).to(device).view(1,-1)
|
| output_ids = model.generate(ids)[0,:]
|
| model.train()
|
| return tokenizer.decode(output_ids.tolist())[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| ds_iter = iter(loader)
|
| for iter in tqdm(range(max_iters+1)):
|
| if iter < ckpt_id:
|
| continue
|
| all_loss = 0.0
|
|
|
| optimizer.zero_grad(set_to_none=True)
|
| for _ in range(gradient_accumulation_steps):
|
|
|
| x, y = next(ds_iter)
|
|
|
| logits,loss = model(x.to(device), y.to(device), device=device)
|
| loss = loss / gradient_accumulation_steps
|
| all_loss += loss.item()
|
|
|
| loss.backward()
|
|
|
| optimizer.step()
|
| scheduler.step()
|
|
|
| if iter % save_interval == 0 or iter == max_iters:
|
| torch.save(model.state_dict(),f'checkpoints/new/{iter}.pt')
|
| print(f"Step {iter} saved.")
|
|
|
| if iter % eval_interval == 0 or iter == max_iters:
|
| print(f"Step: {iter}, Loss: {all_loss}")
|
| print(gen_text("我喜欢你,")) |