Evaluate the model's perplexity on the test set using batch processing. It is expected that model is already on the correct device.
(
model: torch.nn.Module,
pad_token_id: int | None,
testloader: DataLoader[dict[str, torch.Tensor]],
message: str = "Evaluating perplexity"
)
| 204 | |
| 205 | @torch.no_grad() |
| 206 | def evaluate_ppl( |
| 207 | model: torch.nn.Module, |
| 208 | pad_token_id: int | None, |
| 209 | testloader: DataLoader[dict[str, torch.Tensor]], |
| 210 | message: str = "Evaluating perplexity" |
| 211 | ) -> float: |
| 212 | """ |
| 213 | Evaluate the model's perplexity on the test set using batch processing. |
| 214 | It is expected that model is already on the correct device. |
| 215 | """ |
| 216 | sync_gpus() |
| 217 | |
| 218 | start_time = time.time() |
| 219 | |
| 220 | model.eval() |
| 221 | |
| 222 | if pad_token_id: |
| 223 | loss_fn = torch.nn.CrossEntropyLoss(reduction="none", ignore_index=pad_token_id) |
| 224 | else: |
| 225 | loss_fn = torch.nn.CrossEntropyLoss(reduction="none") |
| 226 | |
| 227 | nlls = [] |
| 228 | |
| 229 | logging.info(message) |
| 230 | for batch in tqdm(testloader, desc=message): |
| 231 | logging.debug(f"Evaluating batch {len(nlls)}") |
| 232 | batch = map_tensors(batch, model.model.embed_tokens.weight.device) |
| 233 | logits = model(**batch, use_cache=False).logits |
| 234 | |
| 235 | # shift outputs and labels autoregressively. |
| 236 | logits = logits[:, :-1, :] |
| 237 | shift_labels = batch["input_ids"][:, 1:] |
| 238 | |
| 239 | # CrossEntropyLoss demands data dimension is dimension 1. |
| 240 | nll = loss_fn(logits.permute(0, 2, 1), shift_labels).float() |
| 241 | |
| 242 | mask = shift_labels != loss_fn.ignore_index |
| 243 | nll_means = (nll * mask).sum(dim=1) / mask.sum(dim=1) |
| 244 | nlls.append(nll_means) |
| 245 | |
| 246 | nlls_tensor = torch.cat(nlls) |
| 247 | ppl = torch.exp(nlls_tensor.mean()) |
| 248 | |
| 249 | sync_gpus() |
| 250 | |
| 251 | elapsed = time.time() - start_time |
| 252 | logging.info( |
| 253 | "Time spent on evaluation: %s", |
| 254 | time.strftime("%H:%M:%S.{}".format(str(elapsed % 1)[2:])[:13], time.gmtime(elapsed)), |
| 255 | ) |
| 256 | |
| 257 | return ppl.item() |
| 258 | |
| 259 | def insert_qkv_hooks(model): |
| 260 | query_hooks = [] |
no test coverage detected