| from __future__ import annotations |
|
|
| import json |
| import time |
| from pathlib import Path |
|
|
| import numpy as np |
| import torch |
| from transformers import AutoModel, AutoTokenizer |
|
|
|
|
| IN_PATH = Path("runs/decode_lab/mauve_export_lm1b_latest_1024.jsonl") |
| OUT_PATH = Path("runs/decode_lab/mauve_features_lm1b_latest_1024_gpt2large.npz") |
| MODEL_PATH = "/e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard" |
| MAX_LEN = 256 |
| BATCH_SIZE = 16 |
|
|
|
|
| def load_texts() -> tuple[list[str], list[str], dict[str, list[str]], dict[str, list[str]]]: |
| refs_raw: list[str] = [] |
| refs_stripped: list[str] = [] |
| gen_raw: dict[str, list[str]] = {} |
| gen_stripped: dict[str, list[str]] = {} |
| with IN_PATH.open(encoding="utf-8") as f: |
| for line in f: |
| obj = json.loads(line) |
| typ = obj.get("type") |
| if typ == "reference": |
| refs_raw.append(obj["raw_text"]) |
| refs_stripped.append(obj["stripped_text"]) |
| elif typ == "generated": |
| setting = obj["setting"] |
| key = f"t{float(setting['endpoint_temp']):.2f}_{setting['final_from']}" |
| gen_raw.setdefault(key, []).append(obj["raw_text"]) |
| gen_stripped.setdefault(key, []).append(obj["stripped_text"]) |
| return refs_raw, refs_stripped, gen_raw, gen_stripped |
|
|
|
|
| @torch.no_grad() |
| def featurize( |
| texts: list[str], |
| name: str, |
| tokenizer: AutoTokenizer, |
| model: AutoModel, |
| device: torch.device, |
| ) -> np.ndarray: |
| chunks: list[np.ndarray] = [] |
| t0 = time.time() |
| for start in range(0, len(texts), BATCH_SIZE): |
| batch = texts[start : start + BATCH_SIZE] |
| enc = tokenizer( |
| batch, |
| return_tensors="pt", |
| padding=True, |
| truncation=True, |
| max_length=MAX_LEN, |
| return_attention_mask=True, |
| ).to(device) |
| out = model( |
| input_ids=enc["input_ids"], |
| attention_mask=enc["attention_mask"], |
| output_hidden_states=True, |
| return_dict=True, |
| ) |
| hidden = out.hidden_states[-1] |
| last_idx = enc["attention_mask"].sum(dim=1) - 1 |
| feat = hidden[torch.arange(hidden.size(0), device=device), last_idx] |
| chunks.append(feat.float().cpu().numpy()) |
| if (start // BATCH_SIZE) % 10 == 0: |
| print(f"{name} {start + len(batch)}/{len(texts)}", flush=True) |
| arr = np.concatenate(chunks, axis=0) |
| print(f"{name} {arr.shape} time={time.time() - t0:.1f}s", flush=True) |
| return arr |
|
|
|
|
| def main() -> None: |
| refs_raw, refs_stripped, gen_raw, gen_stripped = load_texts() |
| print( |
| "loaded", |
| len(refs_raw), |
| {key: len(value) for key, value in gen_raw.items()}, |
| flush=True, |
| ) |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH) |
| if tokenizer.pad_token_id is None: |
| tokenizer.pad_token = tokenizer.eos_token |
| tokenizer.pad_token_id = tokenizer.eos_token_id |
| model = AutoModel.from_pretrained(MODEL_PATH, pad_token_id=tokenizer.eos_token_id).to(device).eval() |
|
|
| arrays: dict[str, np.ndarray] = { |
| "ref_raw": featurize(refs_raw, "ref_raw", tokenizer, model, device), |
| "ref_stripped": featurize(refs_stripped, "ref_stripped", tokenizer, model, device), |
| } |
| for key in sorted(gen_raw): |
| arrays[f"gen_{key}_raw"] = featurize(gen_raw[key], f"gen_{key}_raw", tokenizer, model, device) |
| arrays[f"gen_{key}_stripped"] = featurize( |
| gen_stripped[key], |
| f"gen_{key}_stripped", |
| tokenizer, |
| model, |
| device, |
| ) |
| OUT_PATH.parent.mkdir(parents=True, exist_ok=True) |
| np.savez_compressed(OUT_PATH, **arrays) |
| print(f"DONE {OUT_PATH}", flush=True) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|