Taimwe commited on
Commit
3ca4001
·
verified ·
1 Parent(s): 432d798

Diagnostic: dump full replies to diagnose v2 0% ast_rate

Browse files
Files changed (1) hide show
  1. debug_v2_code.py +84 -0
debug_v2_code.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # /// script
2
+ # requires-python = ">=3.10"
3
+ # dependencies = [
4
+ # "torch",
5
+ # "transformers[torch]",
6
+ # "huggingface_hub",
7
+ # "bitsandbytes",
8
+ # "accelerate",
9
+ # ]
10
+ # ///
11
+ """Print FULL replies + extracted blocks for a few code prompts.
12
+
13
+ The eval report only stores reply_first_160, which hides why v2 scored 0% ast_rate
14
+ while the base model scored 93.3%. This dumps everything so we can tell whether the
15
+ model emits broken code or the extractor mis-parses a well-formed reply.
16
+ """
17
+ import json
18
+ import os
19
+ import re
20
+ import sys
21
+
22
+ import torch
23
+ from transformers import (AutoModelForCausalLM, AutoTokenizer,
24
+ BitsAndBytesConfig)
25
+
26
+ REPO = sys.argv[1] if len(sys.argv) > 1 else "Taimwe/securecoder-30b-pro-v2-merged"
27
+ MAXNEW = 1024
28
+
29
+ PROMPTS = [
30
+ "Write a Python function `def is_palindrome(s: str) -> bool:` that checks whether a string reads the same forwards and backwards, ignoring case and non-alphanumeric characters.",
31
+ "Write a Python function `def two_sum(nums: list[int], target: int) -> list[int]:` returning the indices of the two numbers adding to target, or an empty list.",
32
+ "Write a Python function `def flatten(nested: list) -> list:` that flattens an arbitrarily nested list.",
33
+ ]
34
+
35
+ token = os.environ.get("HF_TOKEN")
36
+ tok = AutoTokenizer.from_pretrained(REPO, token=token)
37
+ model = AutoModelForCausalLM.from_pretrained(
38
+ REPO, token=token,
39
+ quantization_config=BitsAndBytesConfig(
40
+ load_in_4bit=True, bnb_4bit_quant_type="nf4",
41
+ bnb_4bit_compute_dtype=torch.bfloat16,
42
+ bnb_4bit_use_double_quant=True),
43
+ dtype=torch.bfloat16, device_map="auto")
44
+
45
+ out = []
46
+ for i, p in enumerate(PROMPTS, 1):
47
+ text = tok.apply_chat_template([{"role": "user", "content": p}],
48
+ tokenize=False, add_generation_prompt=True)
49
+ ids = tok(text, return_tensors="pt", add_special_tokens=False).input_ids.to(model.device)
50
+ with torch.no_grad():
51
+ gen = model.generate(ids, max_new_tokens=MAXNEW, do_sample=False,
52
+ eos_token_id=tok.eos_token_id, pad_token_id=tok.eos_token_id)
53
+ new_ids = gen[0, ids.shape[-1]:]
54
+ reply = tok.decode(new_ids, skip_special_tokens=True)
55
+
56
+ # exactly the eval harness's extraction
57
+ blocks = re.findall(r"```(?:python)?\s*\n(.*?)```", reply, re.S)
58
+ block = max(blocks, key=len) if blocks else None
59
+ if block is None:
60
+ s = reply.find("def ")
61
+ block = reply[s:] if s >= 0 else None
62
+ if block:
63
+ block = re.split(r"\n```", block, maxsplit=1)[0]
64
+ err = None
65
+ if block:
66
+ try:
67
+ compile(block, "<t>", "exec")
68
+ except Exception as exc:
69
+ err = "%s: %s" % (type(exc).__name__, exc)
70
+ out.append({"prompt": p[:80], "n_new_tokens": int(len(new_ids)),
71
+ "n_fenced_blocks": len(blocks),
72
+ "block_len": len(block) if block else 0,
73
+ "compile_error": err, "full_reply": reply})
74
+ print("\n" + "=" * 74)
75
+ print("PROMPT %d new_tokens=%d fenced_blocks=%d block_len=%s"
76
+ % (i, len(new_ids), len(blocks), len(block) if block else 0))
77
+ print("COMPILE:", err or "OK")
78
+ print("-" * 74)
79
+ print(reply[:2500])
80
+
81
+ dest = sys.argv[2] if len(sys.argv) > 2 else "/data/dbg.json"
82
+ with open(dest, "w", encoding="utf-8") as fh:
83
+ json.dump(out, fh, indent=2, default=str)
84
+ print("\nWROTE", dest)