Download qwen2.5-7b_c4_1B/scripts/eval_ppl.py from bit2vec/bitsseal: direct link, hf CLI and curl.
- Browser
- Download file 3.11 kB
-
https://huggingface.co/bit2vec/bitsseal/resolve/main/qwen2.5-7b_c4_1B/scripts/eval_ppl.py
- Command line
-
hf download hf://bit2vec/bitsseal/qwen2.5-7b_c4_1B/scripts/eval_ppl.py
-
curl -L -o eval_ppl.py https://huggingface.co/bit2vec/bitsseal/resolve/main/qwen2.5-7b_c4_1B/scripts/eval_ppl.py
3.11 kB
| #!/usr/bin/env python3 | |
| """Held-out perplexity eval for Bits vs Standard checkpoints (supports encoder variants). | |
| Same held-out set, same metric exp(mean per-token CE). For Bits variants, pass the SAME | |
| --enc_type/--ffn_depth/--W/--nbits used at training so the module structure matches for loading.""" | |
| import argparse, glob, os, math, sys, torch | |
| os.environ['HF_HUB_OFFLINE'] = '1' | |
| os.environ['TRANSFORMERS_OFFLINE'] = '1' | |
| import torch.nn.functional as F | |
| sys.path.insert(0, '/root') | |
| from transformers import AutoConfig, AutoModelForCausalLM | |
| from safetensors.torch import load_file | |
| def build(a): | |
| cfg = AutoConfig.from_pretrained(a.ckpt) | |
| if a.arm == 'standard': | |
| return AutoModelForCausalLM.from_pretrained( | |
| a.ckpt, torch_dtype=torch.bfloat16, attn_implementation='sdpa').cuda().eval() | |
| from bits_llm import swap_in_bits | |
| model = AutoModelForCausalLM.from_config(cfg, torch_dtype=torch.bfloat16, attn_implementation='sdpa') | |
| swap_in_bits(model, a.nbits, a.W, a.seed, enc_type=a.enc_type, ffn_depth=a.ffn_depth, out_scale=0.0) | |
| sd = {} | |
| for f in glob.glob(os.path.join(a.ckpt, '*.safetensors')): | |
| sd.update(load_file(f)) | |
| missing, unexpected = model.load_state_dict(sd, strict=False) | |
| enc_keys = [k for k in sd if 'embed_tokens' in k or '.ffn.' in k or 'in_proj' in k or 'out_proj' in k or 'tfenc' in k] | |
| print(f"[load] tensors={len(sd)} enc_keys={len(enc_keys)} missing={len(missing)} unexpected={len(unexpected)}", flush=True) | |
| if len(enc_keys) == 0: | |
| print("[load][FATAL] no encoder weights in checkpoint", flush=True); sys.exit(3) | |
| return model.cuda().eval() | |
| def evaluate(model, seqs, bs): | |
| tot_loss, tot_tok = 0.0, 0 | |
| for i in range(0, len(seqs), bs): | |
| batch = torch.tensor(seqs[i:i+bs]).cuda() | |
| logits = model(input_ids=batch).logits[:, :-1, :].float() | |
| labels = batch[:, 1:] | |
| loss = F.cross_entropy(logits.reshape(-1, logits.size(-1)), labels.reshape(-1), reduction='sum') | |
| tot_loss += loss.item(); tot_tok += labels.numel() | |
| ml = tot_loss / tot_tok | |
| return ml, math.exp(ml) | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument('--arm', required=True, choices=['bits', 'standard']) | |
| ap.add_argument('--ckpt', required=True) | |
| ap.add_argument('--data', default='/root/heldout_c4val_4000x512.pt') | |
| ap.add_argument('--nbits', type=int, default=256) | |
| ap.add_argument('--W', type=int, default=512) | |
| ap.add_argument('--enc_type', default='mlp', choices=['mlp', 'tfenc']) | |
| ap.add_argument('--ffn_depth', type=int, default=2) | |
| ap.add_argument('--seed', type=int, default=42) | |
| ap.add_argument('--n_seq', type=int, default=4000) | |
| ap.add_argument('--bs', type=int, default=8) | |
| a = ap.parse_args() | |
| model = build(a) | |
| seqs = torch.load(a.data)[:a.n_seq] | |
| ml, ppl = evaluate(model, seqs, a.bs) | |
| print(f"RESULT arm={a.arm} ckpt={a.ckpt} enc={a.enc_type} depth={a.ffn_depth} W={a.W} nbits={a.nbits} " | |
| f"tokens={len(seqs)*len(seqs[0])} eval_loss={ml:.4f} ppl={ppl:.2f}", flush=True) | |
| if __name__ == '__main__': | |
| main() | |