v0.4.9: RCA evidence archived + HANDOVER §0.4
Browse files- scripts/proc_probe.py +52 -0
scripts/proc_probe.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Processor probe: does the eval-path processor call actually embed the
|
| 2 |
+
# image? (NO model weights needed - processor only. Runs in seconds.)
|
| 3 |
+
import os, sys
|
| 4 |
+
os.environ["HF_HUB_DISABLE_XET"] = "1"
|
| 5 |
+
sys.path.insert(0, "/content/qwenjev")
|
| 6 |
+
sys.path.insert(0, "/content/qwenjev/train")
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
from transformers import AutoProcessor
|
| 10 |
+
|
| 11 |
+
proc = AutoProcessor.from_pretrained("Qwen/Qwen3-VL-2B-Instruct")
|
| 12 |
+
|
| 13 |
+
# two DIFFERENT 32x32 frames (drastic difference, like the 109-cell change)
|
| 14 |
+
gA = [[(r * 32 + c) % 16 for c in range(32)] for r in range(32)]
|
| 15 |
+
gB = [[((r * 32 + c) * 7 + 3) % 16 for c in range(32)] for r in range(32)]
|
| 16 |
+
|
| 17 |
+
from qwenjev.vision import render_grid_pil
|
| 18 |
+
imgA, imgB = render_grid_pil(gA), render_grid_pil(gB)
|
| 19 |
+
print("pil images:", imgA.size, imgB.size, imgA.mode)
|
| 20 |
+
|
| 21 |
+
prompt = "<|im_start|>user\nSTATE:\ntest state\n\nQUESTION:\nWhich candidate?<|im_end|>\n<|im_start|>assistant\n"
|
| 22 |
+
|
| 23 |
+
texts = [
|
| 24 |
+
proc.apply_chat_template(
|
| 25 |
+
[{"role": "user", "content": [{"type": "image"},
|
| 26 |
+
{"type": "text", "text": l}]}],
|
| 27 |
+
add_generation_prompt=True, tokenize=False)
|
| 28 |
+
for l in ("CANDIDATE: ACTION1", "CANDIDATE: ACTION6")
|
| 29 |
+
]
|
| 30 |
+
print("--- chat template text[0] head ---")
|
| 31 |
+
print(texts[0][:220].replace("\n", "\\n"))
|
| 32 |
+
|
| 33 |
+
# exactly the eval-path call: images kwarg, padding, pt
|
| 34 |
+
batch = proc(text=texts, images=[imgA, imgB], padding=True, return_tensors="pt")
|
| 35 |
+
print("--- batch keys ---")
|
| 36 |
+
print(sorted(batch.keys()))
|
| 37 |
+
if "pixel_values" in batch:
|
| 38 |
+
pv = batch["pixel_values"]
|
| 39 |
+
print("pixel_values:", tuple(pv.shape), pv.dtype,
|
| 40 |
+
"mean=", float(pv.float().mean()), "std=", float(pv.float().std()))
|
| 41 |
+
print("image_grid_thw:", batch.get("image_grid_thw"))
|
| 42 |
+
# vision token count inside input_ids (Qwen image pad id 151655)
|
| 43 |
+
import torch
|
| 44 |
+
n_vis = int((batch["input_ids"] == 151655).sum())
|
| 45 |
+
print("vision pad tokens in input_ids:", n_vis)
|
| 46 |
+
else:
|
| 47 |
+
print("!!! NO pixel_values: the eval path is TEXT-ONLY — BUG CONFIRMED")
|
| 48 |
+
# text-only comparison: same call WITHOUT images
|
| 49 |
+
batch2 = proc(text=[t.replace("[ vision content omitted ]", "") for t in texts],
|
| 50 |
+
padding=True, return_tensors="pt")
|
| 51 |
+
print("--- no-image batch keys ---", sorted(batch2.keys()))
|
| 52 |
+
print("PROBE_DONE")
|