(model, dataloader, test_dataloader, args, test_type, start_epoch=0, start_time=time.time(),
hop_count=None)
| 122 | |
| 123 | |
| 124 | def train_model(model, dataloader, test_dataloader, args, test_type, start_epoch=0, start_time=time.time(), |
| 125 | hop_count=None): |
| 126 | optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) |
| 127 | total_training_steps = len(dataloader) * args.num_epochs |
| 128 | scheduler = get_linear_schedule_with_warmup( |
| 129 | optimizer, num_warmup_steps=args.warmup_steps, num_training_steps=total_training_steps |
| 130 | ) |
| 131 | |
| 132 | criterion = torch.nn.CrossEntropyLoss(label_smoothing=0.0) |
| 133 | |
| 134 | use_bf16 = args.precision == "bf16" |
| 135 | scaler = torch.cuda.amp.GradScaler(enabled=not use_bf16) |
| 136 | autocast_dtype = torch.bfloat16 if use_bf16 else torch.float16 |
| 137 | |
| 138 | model.train() |
| 139 | os.makedirs(args.checkpoint_dir, exist_ok=True) |
| 140 | |
| 141 | current_epoch = start_epoch |
| 142 | while True: |
| 143 | total_loss = 0.0 |
| 144 | progress_bar = tqdm(dataloader, desc=f"Epoch {current_epoch + 1}", unit="batch") |
| 145 | |
| 146 | for input_ids, target_tokens, attention_mask, input_lengths in progress_bar: |
| 147 | |
| 148 | if args.recurrence_type == 'dynamic': |
| 149 | dynamic_rec = np.random.poisson(args.dynamic_mean) |
| 150 | dynamic_rec = max(args.dynamic_min, min(args.dynamic_max, dynamic_rec)) |
| 151 | model.num_iterations = dynamic_rec |
| 152 | else: |
| 153 | model.num_iterations = args.recurrence |
| 154 | |
| 155 | input_ids = input_ids.to(args.device) |
| 156 | target_tokens = target_tokens.to(args.device) |
| 157 | attention_mask = attention_mask.to(args.device) |
| 158 | |
| 159 | optimizer.zero_grad() |
| 160 | |
| 161 | with torch.cuda.amp.autocast(dtype=autocast_dtype, enabled=True): |
| 162 | outputs = model(input_ids=input_ids, attention_mask=attention_mask) |
| 163 | if args.pred_pos == "last_token": |
| 164 | logits = outputs.logits[:, -1, :] |
| 165 | else: |
| 166 | idx = (input_lengths - 1).view(-1, 1, 1).expand(-1, 1, outputs.logits.size(-1)).to(args.device) |
| 167 | logits = outputs.logits.gather(1, idx).squeeze(1) |
| 168 | loss = criterion(logits, target_tokens) |
| 169 | |
| 170 | if use_bf16: |
| 171 | loss.backward() |
| 172 | if args.max_grad_norm > 0.0: |
| 173 | torch.nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm) |
| 174 | optimizer.step() |
| 175 | else: |
| 176 | scaler.scale(loss).backward() |
| 177 | if args.max_grad_norm > 0.0: |
| 178 | scaler.unscale_(optimizer) |
| 179 | torch.nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm) |
| 180 | scaler.step(optimizer) |
| 181 | scaler.update() |
no test coverage detected