Spaces:
No application file
No application file
File size: 10,217 Bytes
4f2b2f4 |
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# from peft import PeftModel, PeftConfig, get_peft_model
from datasets import load_dataset
from torch.utils.data import DataLoader
from peft import PeftModel, PeftConfig, get_peft_model
from utils.util import flatten_dict,shift_logits
from utils.data import get_bs17k_dataloader,get_llada_bs17k_dataloader,get_dataloader_by_config
from utils.model import get_model,get_llada,get_model_by_config
from utils.loss import compute_loss,compute_llada_loss,compute_normal_loss,compute_loss_by_config
from utils.generation import sample_tokens
# import dataloader
import os
import torch
import argparse
import torch.distributed as dist
from omegaconf import OmegaConf
from tqdm import tqdm
from accelerate import Accelerator
from accelerate.utils import ProjectConfiguration
import ipdb
os.environ['TOKENIZERS_PARALLELISM'] = 'false'
if os.environ.get("DEBUGPY", "0") == "1":
import debugpy
debugpy.listen(("0.0.0.0", 5678))
print(f"Waiting for VS Code debugger attach (PID {os.getpid()})...", flush=True)
debugpy.wait_for_client()
def get_accelerator(config, global_config):
# Select experiment path based on config
if hasattr(global_config, 'paths') and hasattr(global_config.paths, 'experiment'):
root_path = global_config.paths.experiment
else:
root_path = config.root if hasattr(config, 'root') else '/tmp/experiment'
output_dir = os.path.join(root_path, config.exp_name, config.output_dir)
os.makedirs(output_dir, exist_ok=True)
logging_dir = os.path.join(output_dir, config.logging_dir)
project_config = ProjectConfiguration(project_dir=config.output_dir, logging_dir=logging_dir)
accelerator = Accelerator(
log_with=None if config.report_to == 'no' else config.report_to,
mixed_precision=config.mixed_precision,
project_config=project_config,
gradient_accumulation_steps=config.gradient_accumulation_steps,
)
return accelerator, output_dir
def main(args):
config = OmegaConf.load(args.config)
accelerator, output_dir = get_accelerator(config.train, config)
# Use unified model and data loading functions
denoiser, tokenizer = get_model_by_config(config)
dataloader = get_dataloader_by_config(tokenizer, config.data, config)
if config.train.decoder_resume_path is not None:
ckpt = torch.load(config.train.decoder_resume_path, map_location='cpu', weights_only=True)
if config.train.skipped_keys:
ckpt = {k: v for k, v in ckpt.items() if k not in config.train.skipped_keys}
m, u = denoiser.load_state_dict(ckpt, strict=False)
if accelerator.is_main_process:
print(f'model ckpt loaded from {config.train.decoder_resume_path}')
# ckpt = torch.load(config.train.head_resume_path, map_location='cpu', weights_only=True)
# if config.train.skipped_keys:
# ckpt = {k: v for k, v in ckpt.items() if k not in config.train.skipped_keys}
# m, u = denoiser.lm_head.load_state_dict(ckpt, strict=False)
# if accelerator.is_main_process:
# print(f'model ckpt loaded from {config.train.head_resume_path}')
global_step = config.train.global_step if config.train.global_step is not None else 0
params_to_learn = list(param for param in denoiser.parameters() if param.requires_grad)
optimizer = torch.optim.AdamW(
params_to_learn,
lr = config.train.lr,
betas = (0.9, 0.95),
weight_decay = 5e-2,
eps = 1e-8,
)
denoiser, dataloader, optimizer = accelerator.prepare(denoiser, dataloader, optimizer)
config.device_count = accelerator.num_processes
if accelerator.is_main_process:
accelerator.init_trackers(config.train.wandb_proj, config=flatten_dict(config))
training_done = False
epoch = 0
progress_bar = tqdm(
total = config.train.num_iters,
initial = global_step,
desc = 'Steps',
disable = not accelerator.is_local_main_process,
)
if accelerator.is_main_process:
print(f'Learnable parameters: {sum(p.numel() for p in params_to_learn if p.requires_grad) / 1e9} B')
while not training_done:
if accelerator.is_main_process:
print(f'Epoch: {epoch}')
for batch in dataloader:
with accelerator.accumulate([denoiser]):
denoiser.train()
ipdb.set_trace()
input_ids = batch['data']
# print("input_ids",input_ids.dtype)
question_length = batch['question_length']
# Use unified loss function selection
losses = compute_loss_by_config(
input_ids,
denoiser,
question_length,
block_size = config.train.block_size,
mask_id = config.denoiser.encoder.mask_id,
enable_shift = config.train.enable_shift,
share_steps = config.train.share_steps,
self_align = config.train.self_align,
feature_align = config.train.feature_align,
self_step = config.train.self_step,
eos_id = tokenizer.eos_token_id,
config = config
)
if config.train.share_steps > 1:
loss_tgt = losses['loss']
# loss_1 = losses['loss_1']
# loss_2 = losses['loss_2']
else:
raise NotImplementedError
torch.cuda.empty_cache()
accelerator.backward(loss_tgt)
if accelerator.sync_gradients:
accelerator.clip_grad_norm_(params_to_learn, 1.0)
optimizer.step()
optimizer.zero_grad()
if accelerator.sync_gradients:
global_step += 1
progress_bar.update(1)
logs = dict()
loss_tgt = accelerator.gather(loss_tgt.detach()).mean().item()
logs['loss'] = loss_tgt
# if config.train.share_steps > 1:
# loss_1 = accelerator.gather(loss_1.detach()).mean().item()
# loss_2 = accelerator.gather(loss_2.detach()).mean().item()
# logs['loss_1'] = loss_1
# logs['loss_2'] = loss_2
accelerator.log(logs, step=global_step)
progress_bar.set_postfix(**logs)
if global_step > 0 and global_step % config.train.eval_every == 0 and accelerator.is_main_process:
denoiser.eval();
question = 'Henry made two stops during his 60-mile bike trip. He first stopped after 20 miles. His second stop was 15 miles before the end of the trip. How many miles did he travel between his first and second stops?'
# prompt = tokenizer(question)['input_ids']
# prompt = torch.tensor(prompt).to(accelerator.device).unsqueeze(0)
messages = [
{"role": "user", "content": question}
]
prompt = tokenizer.apply_chat_template(
messages, return_tensors="pt", return_dict=True, add_generation_prompt=True
).input_ids
prompt = prompt.to(accelerator.device)
mask_id = 151666
gen_len = 512 - prompt.shape[1]
temperature = 0.2
top_p = 0.95
x_t = torch.cat([prompt, torch.tensor([[mask_id]*gen_len]).to(accelerator.device)], dim=1)
with torch.inference_mode():
for i in range(gen_len):
mask_index = (x_t == mask_id)
if i % 2 == 0:
z_t = denoiser.module.encoder(x_t, output_hidden_states=True).hidden_states[-1]
hidden_state = denoiser.module.decoder(x_t, z_t)
logits = denoiser.module.encoder.lm_head(hidden_state)
else:
hidden_state = denoiser.module.decoder(x_t, z_t)
logits = denoiser.module.lm_head(hidden_state)
if config.train.enable_shift:
logits = shift_logits(logits)
mask_logits = logits[mask_index]
confidence, x0 = sample_tokens(mask_logits, temperature, top_p=top_p, top_k=None, neg_entropy=True)
number_transfer_tokens = 1
_, transfer_index = torch.topk(confidence, number_transfer_tokens)
x0_ = torch.zeros_like(x0, device=accelerator.device, dtype=torch.long) + mask_id
x0_[transfer_index] = x0[transfer_index].clone()
x_t[mask_index] = x0_
answer = tokenizer.batch_decode(x_t[:, prompt.shape[1]:], skip_special_tokens=True)[0]
print(answer)
accelerator.wait_for_everyone()
if global_step > 0 and global_step % config.train.save_every == 0 and accelerator.is_main_process:
denoiser.eval()
decoder_state_dict = accelerator.unwrap_model(denoiser).save_pretrained(os.path.join(output_dir, f"Decoder-{config.train.exp_name}-{global_step // 1000}k"))
# lmhead_state_dict = accelerator.unwrap_model(denoiser).lm_head.state_dict()
# torch.save(lmhead_state_dict, os.path.join(output_dir, f"LMhead-{config.train.exp_name}-{global_step // 1000}k"))
accelerator.wait_for_everyone()
if global_step >= config.train.num_iters:
training_done = True
break
epoch += 1
accelerator.end_training()
if dist.is_initialized():
dist.destroy_process_group()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--config', type=str, default='config/dream.yaml')
args = parser.parse_args()
main(args) |