Views
No views yet
Qwen/Qwen3.6-27B that reads a residual-stream
activation you inject and verbalizes the model's internal "workspace" (what it is about to
generate). This is an RL (GRPO) checkpoint, step 95/100, whose reward combines a frozen
reconstruction reader with a joint/sum surprisal-shaping term that pushes the verbalization to be
off-policy (unlikely as a literal continuation) while keeping reconstruction high.Σ_t log P_base(rollout | ctx) — not the length-normalized mean. λ is set adaptively each step
so the surprisal term's GRPO influence ratio is pinned at ~10% of the reconstruction term's
within-group spread.㈜ (id 158983).nla_meta.yaml → prompt_templates.actor) with ㈜ in the
<concept>…</concept> slot; chat template with enable_thinking=False.meansub-norm variant, which injects the unit-mean-centered activation).max_new_tokens = 12, lr 1e-4, adaptive-λ (target influence 0.10).r = 64, α = 16, rsLoRA, scope = all (12 target module types), on Qwen/Qwen3.6-27B.1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3from peft import PeftModel
4# repo helpers: register_karvonen_hook (block-1 norm-matched inject), the actor template, prompt ids
5from nla.utils.hooks import register_karvonen_hook
6from nla.schema import compute_canonical_neighbors
7from nla.datagen.injection_tokens import find_injection_token
8
9dev = "cuda"
10ACTOR_TEMPLATE = ( # == nla_meta.yaml -> prompt_templates.actor
11 "You are shown an internal activation vector captured from a language model as it reads a "
12 "passage of text. The vector, enclosed in <concept> tags, is taken at one position and encodes "
13 "what the model is about to generate next. Output the text the model most likely produces "
14 "immediately after this point.\n\n<concept>{injection_char}</concept>")
15
16tok = AutoTokenizer.from_pretrained("Qwen/Qwen3.6-27B")
17base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.6-27B", torch_dtype=torch.bfloat16).to(dev).eval()
18model = PeftModel.from_pretrained(base, "ceselder/skip-lens-qwen36-27b-surprisal-joint-iter95").eval()
19inj, inj_id = find_injection_token(tok)
20L, R = compute_canonical_neighbors(tok, ACTOR_TEMPLATE, inj, inj_id)
21vref = [None]; register_karvonen_hook(model, vref, inj_id, L, R); model._fl_vref = vref
22
23s = tok.apply_chat_template([{"role": "user", "content": ACTOR_TEMPLATE.format(injection_char=inj)}],
24 tokenize=False, add_generation_prompt=True, enable_thinking=False)
25pt = torch.tensor([tok.encode(s, add_special_tokens=False)], device=dev)
26
27# h62 = the L62 residual you grabbed from the base model at your position of interest, shape [5120]
28model._fl_vref[0] = h62.float().view(1, -1) # norm-matched inject; raw activation (no mean-centering)
29out = model.generate(pt, max_new_tokens=12, do_sample=True, temperature=0.7, top_p=0.95)
30print(tok.decode(out[0, pt.shape[1]:], skip_special_tokens=True))
31model._fl_vref[0] = Nonenla_meta.yaml.mean_dir files are not relevant here (raw injection); those belong to the meansub-norm sibling.