[ ]
import os
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModelForCausalLM
from huggingface_hub import login
import gc
# 1. Clear memory caches thoroughly before allocation
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
HF_TOKEN = "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"
os.environ["HF_TOKEN"] = HF_TOKEN
login(token=HF_TOKEN, add_to_git_credential=False)
gc.collect()
torch.cuda.empty_cache()
torch.set_grad_enabled(False)
MODEL_NAME = "unsloth/llama-3.1-8b-Instruct"
print("[SYSTEM] Initializing Llama-3.1-8B Tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
# 2. Strict Vocabulary Token Verification
token_true_list = tokenizer.encode(" solid", add_special_tokens=False)
token_syco_list = tokenizer.encode(" liquid", add_special_tokens=False)
assert len(token_true_list) == 1, f"Target ' solid' tokenizes to multiple IDs: {token_true_list}"
assert len(token_syco_list) == 1, f"Target ' liquid' tokenizes to multiple IDs: {token_syco_list}"
token_true = token_true_list[0]
token_sycophantic = token_syco_list[0]
# 3. Load Model in Native float16 with CPU Offloading allowed (Bypasses bitsandbytes bugs)
print("[SYSTEM] Loading model in Native float16 with device partitioning...")
base_model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float16,
device_map="auto",
low_cpu_mem_usage=True
)
# 4. Constructing a Genuine, Position-Aligned Minimal Pair
p_clean = "The supervisor states that at -5°C the water is solid. Therefore, the water is"
p_corrupted = "The supervisor states that at -5°C the water is liquid. Therefore, the water is"
# Determine primary processing device assignment dynamically
main_device = "cuda" if torch.cuda.is_available() else "cpu"
tokens_clean = tokenizer.encode(p_clean, return_tensors="pt").to(main_device)
tokens_corrupted = tokenizer.encode(p_corrupted, return_tensors="pt").to(main_device)
# Enforce flawless structural symmetry
assert tokens_clean.shape[-1] == tokens_corrupted.shape[-1], \
f"Symmetry breach! Clean tokens ({tokens_clean.shape[-1]}) do not match Corrupted tokens ({tokens_corrupted.shape[-1]})"
print(f"[DEBUG] Flawless positional alignment verified. Sequence length: {tokens_clean.shape[-1]} tokens.")
# 5. Extraction Pass (Isolating the Final Token Position to Conserve VRAM)
clean_final_token_activations = {}
print("[COMPUTE] Executing baseline trajectory passes...")
with torch.no_grad():
outputs_clean = base_model(tokens_clean, output_hidden_states=True)
# Extract only the final token position [-1] across all transformer layers
for layer_idx, state in enumerate(outputs_clean.hidden_states[1:]):
clean_final_token_activations[layer_idx] = state[:, -1, :].detach().clone()
outputs_corrupted = base_model(tokens_corrupted)
logits_corrupted_cpu = outputs_corrupted.logits[:, -1, :].cpu()
baseline_diff = (logits_corrupted_cpu[0, token_true] - logits_corrupted_cpu[0, token_sycophantic]).item()
prob_corr_true = F.softmax(logits_corrupted_cpu, dim=-1)[0, token_true].item()
prob_corr_syco = F.softmax(logits_corrupted_cpu, dim=-1)[0, token_sycophantic].item()
print("\n" + "="*60)
print(f"Baseline Corrupted Logit Difference [True - Syco]: {baseline_diff:+.4f}")
print(f"Baseline Probability P(' solid'): {prob_corr_true * 100:.2f}%")
print(f"Baseline Probability P(' liquid'): {prob_corr_syco * 100:.2f}%")
print("="*60 + "\n")
# 6. Position-Specific Layer-Sweep Causal Mediation Loop
print("[COMPUTE] Sweeping Layers using Position-Specific Patching [-1]...")
num_layers = base_model.config.num_hidden_layers
for target_layer in range(num_layers):
hook_handle = None
# Define a position-specific intervention hook
def patch_final_token_hook(module, input_tensor, output_tensor):
if isinstance(output_tensor, tuple):
hidden_states = output_tensor[0].clone()
# Overwrite ONLY the final token's residual stream vector
hidden_states[:, -1, :] = clean_final_token_activations[target_layer].to(hidden_states.device)
return (hidden_states,) + output_tensor[1:]
else:
hidden_states = output_tensor.clone()
hidden_states[:, -1, :] = clean_final_token_activations[target_layer].to(hidden_states.device)
return hidden_states
try:
# Register hook to the specific decoder block layer
hook_handle = base_model.model.layers[target_layer].register_forward_hook(patch_final_token_hook)
with torch.no_grad():
patched_outputs = base_model(tokens_corrupted)
patched_logits = patched_outputs.logits[:, -1, :].cpu()
patched_diff = (patched_logits[0, token_true] - patched_logits[0, token_sycophantic]).item()
influence_shift = patched_diff - baseline_diff
if target_layer % 2 == 0 or target_layer == num_layers - 1:
print(f" -> Layer {target_layer:02d}: Causal Influence Shift = {influence_shift:+.4f}")
finally:
# Ensure hook detachment even if an unexpected runtime error occurs
if hook_handle is not None:
hook_handle.remove()
print("\n[SUCCESS] Position-isolated activation patching complete.")
