diag5.py 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #!/usr/bin/env python3
  2. """Boot-3 probe sequence (no warm-up ran): is the prefill path clean on a virgin engine?
  3. Then replay the warm-up pieces one at a time with a probe after each."""
  4. import json, time, sys, urllib.request, concurrent.futures as cf, math, random
  5. import os; sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); from batchtest import PROMPTS, garbage
  6. URL = "http://10.0.0.1:8888/v1/chat/completions"
  7. core = " Now write a vivid short story about a lighthouse keeper's last winter. Prose only."
  8. def prompt_with(n_fill, seed):
  9. rnd = random.Random(seed)
  10. return (f"Record {seed}: " + " ".join(str(rnd.randint(0, 9)) for _ in range(n_fill)) + "." + core) if n_fill else core.strip()
  11. def gen(prompt, n=40, temp=0.0, logprobs=True):
  12. body = dict(model="deepseek-v4.1-flash", temperature=temp, max_tokens=n, stream=False,
  13. chat_template_kwargs={"thinking": False}, messages=[{"role": "user", "content": prompt}])
  14. if logprobs: body["logprobs"] = True; body["top_logprobs"] = 1
  15. r = json.load(urllib.request.urlopen(urllib.request.Request(URL, data=json.dumps(body).encode(), headers={"Content-Type": "application/json"}), timeout=900))
  16. c = r["choices"][0]; lp = [t["logprob"] for t in c["logprobs"]["content"]] if logprobs else [None]
  17. return r["usage"]["prompt_tokens"], c["message"]["content"], lp
  18. def probe(tag, n_fill=280, seed=None):
  19. seed = seed or random.randint(1, 10**6)
  20. pt, txt, lp = gen(prompt_with(n_fill, seed))
  21. bad = garbage(txt) or lp[0] is None
  22. print(f"PROBE {tag}: prompt_tokens={pt} lp0={'NaN' if lp[0] is None else round(lp[0],3)} {'GARBAGE' if bad else 'ok'} {txt[:60]!r}", flush=True)
  23. return bad
  24. def batch(tag, k, n=40):
  25. with cf.ThreadPoolExecutor(k) as ex:
  26. rs = list(ex.map(lambda i: gen(PROMPTS[i % 6], n), range(k)))
  27. bad = sum(1 for _, t, lp in rs if garbage(t) or lp[0] is None)
  28. print(f"BATCH {tag} (bs={k}): {bad}/{k} garbled " + " | ".join(t[:25].replace(chr(10),' ') for _, t, _ in rs), flush=True)
  29. return bad
  30. print(f"== diag5 {time.strftime('%H:%M:%S')} virgin engine (WARMUP=0) ==")
  31. b = probe("virgin 600-token prompt")
  32. b += probe("virgin 150-token prompt", n_fill=55)
  33. b += batch("virgin", 3)
  34. b += batch("virgin", 4)
  35. if b:
  36. print("RESULT: garbage on a virgin engine -> the warm-up is not the trigger; configuration bisect next"); sys.exit(0)
  37. print("== clean so far: replay the warm-up pieces, probe after each ==")
  38. filler = ('The quick brown fox jumps over the lazy dog near the riverbank while the sun sets slowly behind the distant hills. ')
  39. for words in (12, 200, 900, 3600):
  40. p = (filler * (words // 20 + 1)) + 'Summarise the text above in one sentence.'
  41. pt, txt, lp = gen(p, 24, logprobs=False)
  42. print(f"warm-up piece ~{words} words: prompt_tokens={pt} {txt[:50]!r}", flush=True)
  43. if probe(f"after warm-up {words} words") or batch(f"after warm-up {words} words", 3):
  44. print(f"RESULT: state broke after the ~{words}-word warm-up prompt"); sys.exit(0)
  45. wb = ['Explain how a hash table handles collisions in two sentences.', 'List the steps of the TCP three-way handshake.',
  46. 'What is the capital of France? Answer in one word.', 'Write a haiku about mountains.']
  47. with cf.ThreadPoolExecutor(4) as ex: list(ex.map(lambda p: gen(p, 48, logprobs=False), wb))
  48. if probe("after warm-up batch of 4") or batch("after warm-up batch of 4", 3):
  49. print("RESULT: state broke after the warm-up batch of 4"); sys.exit(0)
  50. print("== still clean: longer soak: sweep 100..9000 tokens and repeated batches ==")
  51. for k, target in enumerate((100, 300, 900, 1700, 2300, 3000, 4500, 9000)):
  52. b += probe(f"sweep {target}", n_fill=max(0, (target - 45) // 2), seed=3000 + k)
  53. for rep in range(3):
  54. b += batch(f"soak rep{rep}", 3) + batch(f"soak rep{rep}", 4)
  55. print(f"RESULT: {b} garbled after the full replay; " + ("CLEAN engine" if b == 0 else "garbage appeared late"))