MCPcopy Create free account
hub / github.com/Paper2Poster/Paper2Poster / get_ppl

Function get_ppl

utils/poster_eval_utils.py:552–617  ·  view source on GitHub ↗

Compute perplexity for arbitrarily long *text* using a sliding‑window approach. Parameters ---------- text : str The input string (any length). model_name : str, optional HF Hub id of the model to use, by default "meta-llama/Llama-2-7b-hf". stride : int, optional

(
    text: str,
    model_name: str = "meta-llama/Llama-2-7b-hf",
    stride: int = 512,
)

Source from the content-addressed store, hash-verified

550 return math.exp(-sum(valid) / len(valid))
551
552def get_ppl(
553 text: str,
554 model_name: str = "meta-llama/Llama-2-7b-hf",
555 stride: int = 512,
556) -> float:
557 """Compute perplexity for arbitrarily long *text* using a sliding‑window approach.
558
559 Parameters
560 ----------
561 text : str
562 The input string (any length).
563 model_name : str, optional
564 HF Hub id of the model to use, by default "meta-llama/Llama-2-7b-hf".
565 stride : int, optional
566 Overlap between successive windows. 512 tends to work well for most
567 Transformer LMs with a 2 k context. Increase it for higher accuracy at
568 the cost of more compute.
569
570 Returns
571 -------
572 float
573 Per‑token perplexity under the given model.
574 """
575 # Load tokenizer / model once per call (cache makes subsequent calls cheap)
576 tokenizer = AutoTokenizer.from_pretrained(model_name)
577 model = AutoModelForCausalLM.from_pretrained(
578 model_name,
579 torch_dtype=torch.float16,
580 device_map="auto", # place on GPU if available
581 )
582 model.eval()
583
584 # Encode the whole string in one shot
585 encodings = tokenizer(text, return_tensors="pt")
586 input_ids = encodings.input_ids[0]
587
588 # Model context length (e.g. 2048 for Llama‑2)
589 max_len = model.config.max_position_embeddings
590
591 # --- Short input: fits in a single window --------------------------------
592 if input_ids.size(0) <= max_len:
593 with torch.no_grad():
594 out = model(input_ids.unsqueeze(0).to(model.device), labels=input_ids.unsqueeze(0).to(model.device))
595 return torch.exp(out.loss).item()
596
597 # --- Long input: sliding window with overlap -----------------------------
598 nlls = [] # negative‑log‑likelihoods (already multiplied by #tokens scored)
599 for i in range(0, input_ids.size(0), stride):
600 begin_loc = max(i + stride - max_len, 0)
601 end_loc = min(i + stride, input_ids.size(0))
602 trg_len = end_loc - i # tokens we actually score in this window
603
604 ids_chunk = input_ids[begin_loc:end_loc]
605 labels = ids_chunk.clone()
606 labels[:-trg_len] = -100 # mask out purely‑context tokens
607
608 with torch.no_grad():
609 out = model(ids_chunk.unsqueeze(0).to(model.device), labels=labels.unsqueeze(0).to(model.device))

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected