Analyze transformer feed-forward layers as key-value memories, extract activations, identify trigger examples, and compute key-value agreement in transformer language models
Analyze transformer feed-forward layers as key-value memories, extract activations, identify trigger examples, and compute key-value agreement in transformer language models
Demo Scripts
scripts/compute_key_value_agreement.py
#!/usr/bin/env python3"""
Compute Key-Value Agreement in Transformer Feed-Forward Layers
This script demonstrates the key-value agreement analysis for transformer
feed-forward layers, showing how values correspond to their associated keys.
Requirements:
- ff-layers installed
- Pre-extracted trigger examples (textual format)
- ~150GB RAM for full analysis
"""import argparse
import json
import os
import sys
from pathlib import Path
from typing importDict, List, Tuple, Optionalimport pandas as pd
# Add ff-layers to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
defcheck_memory_requirements():
"""
Check if system has sufficient memory for analysis.
"""import psutil
mem = psutil.virtual_memory()
total_gb = mem.total / (1024 ** 3)
available_gb = mem.available / (1024 ** 3)
print(f"System Memory Status:")
print(f" Total: {total_gb:.1f} GB")
print(f" Available: {available_gb:.1f} GB")
if total_gb < 150:
print("WARNING: Full key-value agreement analysis requires ~150GB RAM")
print("Consider using a subset of data or a machine with more memory")
returnFalsereturnTruedefcompute_agreement(
model_dir: str,
data_dir: str,
output_base: str) -> None:
"""
Compute agreement between keys and values.
Args:
model_dir: Path to model checkpoint directory
data_dir: Directory with trigger examples (textual format)
output_base: Base name for output files (will create .tsv and .json)
"""
cmd_parts = [
'python', 'analysis/key_value_agreement.py',
'--model_dir', model_dir,
'--data_dir', data_dir,
'--output_base', output_base
]
import subprocess
print(f"Computing key-value agreement...")
print(f"This may take significant time and memory...")
try:
result = subprocess.run(
cmd_parts,
check=True,
capture_output=True,
text=True
)
print(f"Agreement computation completed!")
print(f"Output files: {output_base}.tsv and {output_base}.json")
except subprocess.CalledProcessError as e:
print(f"Error during computation: {e}")
if e.stdout:
print(f"stdout: {e.stdout}")
if e.stderr:
print(f"stderr: {e.stderr}")
raisedefanalyze_agreement_results(tsv_file: str) -> Dict:
"""
Analyze key-value agreement results from TSV file.
Args:
tsv_file: Path to TSV file with agreement results
Returns:
Dictionary with analysis statistics
"""try:
# Load TSV file
df = pd.read_csv(tsv_file, sep='\t')
stats = {
'total_keys': len(df),
'mean_agreement': df['agreement'].mean() if'agreement'in df.columns else0,
'std_agreement': df['agreement'].std() if'agreement'in df.columns else0,
'layers': df['layer'].unique().tolist() if'layer'in df.columns else [],
}
# Find keys with highest agreementif'agreement'in df.columns:
top_keys = df.nlargest(10, 'agreement')[['layer', 'dimension', 'agreement']]
stats['top_agreement_keys'] = top_keys.to_dict('records')
return stats
except FileNotFoundError:
print(f"File not found: {tsv_file}")
return {}
except Exception as e:
print(f"Error analyzing results: {e}")
return {}
defcreate_subset_data(
input_dir: str,
output_dir: str,
max_keys: int = 100) -> str:
"""
Create a subset of trigger example data for testing.
Args:
input_dir: Directory with full trigger examples
output_dir: Directory for subset output
max_keys: Maximum number of keys to include
Returns:
Path to subset directory
"""import shutil
# Create output directory
Path(output_dir).mkdir(parents=True, exist_ok=True)
# Get list of files
input_path = Path(input_dir)
files = list(input_path.glob('*.txt'))[:max_keys]
print(f"Creating subset with {len(files)} keys...")
for file in files:
dest = Path(output_dir) / file.name
shutil.copy2(file, dest)
print(f"Subset created in: {output_dir}")
return output_dir
defvisualize_agreement(json_file: str, output_plot: str = None):
"""
Create visualization of key-value agreement patterns.
Args:
json_file: Path to JSON file with agreement data
output_plot: Path to save plot (optional)
"""try:
import matplotlib.pyplot as plt
import numpy as np
withopen(json_file, 'r') as f:
data = json.load(f)
# Extract agreement scores per layer
layer_agreements = {}
for key, value in data.items():
ifisinstance(value, dict) and'layer'in value:
layer = value['layer']
agreement = value.get('agreement', 0)
if layer notin layer_agreements:
layer_agreements[layer] = []
layer_agreements[layer].append(agreement)
# Create plot
fig, ax = plt.subplots(figsize=(12, 6))
layers = sorted(layer_agreements.keys())
agreements = [layer_agreements[l] for l in layers]
# Box plot
bp = ax.boxplot(agreements, labels=layers)
ax.set_xlabel('Layer')
ax.set_ylabel('Agreement Score')
ax.set_title('Key-Value Agreement Across Layers')
ax.grid(True, alpha=0.3)
if output_plot:
plt.savefig(output_plot, dpi=150, bbox_inches='tight')
print(f"Plot saved to: {output_plot}")
else:
plt.show()
except ImportError:
print("Matplotlib not installed. Skipping visualization.")
except Exception as e:
print(f"Error creating visualization: {e}")
defmain():
"""
Main function for key-value agreement analysis.
"""
parser = argparse.ArgumentParser(
description='Compute key-value agreement in transformer FF layers'
)
parser.add_argument(
'--model-dir',
type=str,
default='checkpoints/adaptive_lm_wiki103.v2/',
help='Path to model checkpoint directory'
)
parser.add_argument(
'--data-dir',
type=str,
help='Directory with trigger examples (textual format)'
)
parser.add_argument(
'--output-base',
type=str,
default='key_value_agreement',
help='Base name for output files'
)
parser.add_argument(
'--analyze-only',
type=str,
help='Only analyze existing TSV file'
)
parser.add_argument(
'--subset',
type=int,
help='Create and use subset with N keys (for testing)'
)
parser.add_argument(
'--visualize',
action='store_true',
help='Create visualization of results'
)
args = parser.parse_args()
if args.analyze_only:
# Analyze existing results
stats = analyze_agreement_results(args.analyze_only)
print("\n=== Key-Value Agreement Analysis ===")
print(f"Total keys: {stats.get('total_keys', 0)}")
print(f"Mean agreement: {stats.get('mean_agreement', 0):.4f}")
print(f"Std agreement: {stats.get('std_agreement', 0):.4f}")
print(f"Number of layers: {len(stats.get('layers', []))}")
if'top_agreement_keys'in stats:
print("\nTop 10 Keys by Agreement:")
for key in stats['top_agreement_keys']:
print(f" Layer {key['layer']}, Dim {key['dimension']}: {key['agreement']:.4f}")
if args.visualize:
json_file = args.analyze_only.replace('.tsv', '.json')
if os.path.exists(json_file):
visualize_agreement(json_file, 'agreement_plot.png')
else:
# Check memory requirementsifnot check_memory_requirements():
response = input("\nContinue anyway? (y/n): ")
if response.lower() != 'y':
print("Exiting...")
return# Handle subset creation if requested
data_dir = args.data_dir
if args.subset and data_dir:
subset_dir = f"{data_dir}_subset_{args.subset}"
data_dir = create_subset_data(data_dir, subset_dir, args.subset)
ifnot data_dir:
print("Error: --data-dir is required")
return# Compute agreement
compute_agreement(
model_dir=args.model_dir,
data_dir=data_dir,
output_base=args.output_base
)
# Analyze results
tsv_file = f"{args.output_base}.tsv"if os.path.exists(tsv_file):
stats = analyze_agreement_results(tsv_file)
print("\n=== Results Summary ===")
print(f"Mean agreement: {stats.get('mean_agreement', 0):.4f}")
if args.visualize:
json_file = f"{args.output_base}.json"if os.path.exists(json_file):
visualize_agreement(json_file, f"{args.output_base}_plot.png")
if __name__ == "__main__":
main()
"""
Export predictions from pickle to CSV for easier analysis.
Args:
pickle_file: Path to pickle file
output_csv: Path for output CSV file
max_rows: Maximum rows to export (None for all)
"""
try
with
open
'rb'
as
# Limit rows if specified
if
# Convert complex columns to strings for CSV
for
in
if
'object'
# Check if column contains lists/arrays
0
if
not
else
None
if
isinstance
list
lambda
str
if
is
not
None
else
''
# Export to CSV
False
print
f"Exported {len(df)} rows to: {output_csv}"
except
as
print
f"Error exporting to CSV: {e}"
def
compare_extraction_modes
dim_pickle: str,
layer_pickle: str
None
"""
Compare results from dimension-level and layer-level extractions.
Args:
dim_pickle: Path to dimension-level pickle file
layer_pickle: Path to layer-level pickle file
"""
data_file: str,
model_dir: str,
output_dir: str,
num_sentences: int = 100
Tuple
str
str
"""
Create sample analysis with both extraction modes.
Args:
data_file: Path to data file
model_dir: Path to model directory
output_dir: Output directory for results
num_sentences: Number of sentences to analyze
Returns:
Tuple of (dim_pickle_path, layer_pickle_path)
"""
True
True
# Extract dimension-level predictions
f'dim_{num_sentences}sent.pkl'
'dim'
# Extract layer-level predictions
f'layer_{num_sentences}sent.pkl'
'layer'
return
def
main
"""
Main function for prediction extraction and analysis.
"""
"""
Extract trigger examples for transformer keys.
Args:
data_file: Path to tokenized data file
model_dir: Path to model checkpoint directory
output_file: Path for output JSONL file
max_sentences: Number of sentences to process (-1 for all)
top_k: Number of top trigger examples per key
dims: Specific dimensions to analyze (None for all)
extract_mode: Extraction mode ('layer-raw', 'dim', 'layer')
"""
# Build command
'python'
'analysis/generate_outputs.py'
'--data_file'
'--model_dir'
'--get_trigger_examples'
'--max_sentences'
str
'--top_k_trigger_examples'
str
'--extract_mode'
'--output_file'
# Add specific dimensions if provided
if
'--dims_for_analysis'
str
for
in
# Execute command
import
print
f"Executing: {' '.join(cmd_parts)}"
try
True
True
True
print
"Extraction completed successfully!"
print
f"Output saved to: {output_file}"
except
as
print
f"Error during extraction: {e}"
if
print
f"stdout: {e.stdout}"
if
print
f"stderr: {e.stderr}"
raise
def
convert_to_textual
input_jsonl: str,
model_dir: str,
output_dir: str
None
"""
Convert JSONL output to readable text files.
Args:
input_jsonl: Path to input JSONL file
model_dir: Path to model checkpoint directory
output_dir: Directory for text output files
"""
'python'
'analysis/trigger_examples_jsonl_to_textual.py'
'--input_file'
'--model_dir'
'--output_dir'
import
print
f"Converting to textual format..."
try
True
True
True
print
f"Conversion completed! Output in: {output_dir}"
except
as
print
f"Error during conversion: {e}"
raise
def
analyze_trigger_examples
jsonl_file: str
Dict
str
Any
"""
Analyze extracted trigger examples from JSONL file.
Args:
jsonl_file: Path to JSONL file with trigger examples
Returns:
Dictionary with analysis statistics
"""
'total_keys'
0
'layers'
set
'dimensions'
set
'examples_per_key'
try
with
open
'r'
as
for
in
'total_keys'
1
# Extract layer and dimension info
if
'layer'
in
'layers'
'layer'
if
'dimension'
in
'dimensions'
'dimension'
if
'examples'
in
'examples_per_key'
len
'examples'
# Convert sets to lists for JSON serialization
'layers'
sorted
list
'layers'
'dimensions'
sorted
list
'dimensions'
# Calculate average examples per key
if
'examples_per_key'
'avg_examples'
sum
'examples_per_key'
len
'examples_per_key'
return
except
print
f"File not found: {jsonl_file}"
return
except
as
print
f"Error parsing JSON: {e}"
return
def
main
"""
Main function to demonstrate trigger example extraction.
"""
'Extract trigger examples from transformer FF layers'