interp-engine 1.11.2__tar.gz → 1.11.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {interp_engine-1.11.2 → interp_engine-1.11.3}/PKG-INFO +1 -1
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/requests.py +9 -5
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/static.py +55 -37
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/steering.py +26 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/pyproject.toml +1 -1
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_steer_math_parity.py +108 -0
- interp_engine-1.11.3/tests/test_steer_ops_per_site_gpu.py +132 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_hyper_connections.py +2 -2
- {interp_engine-1.11.2 → interp_engine-1.11.3}/.gitignore +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/LICENSE +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/README.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/README.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/__init__.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/bench_spec.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/cells.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/probe.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/probe_lens_stream.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/publish.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/report_bench.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__eager.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__vllm-cudagraph.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__vllm-static.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__vllm.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__eager.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__vllm-cudagraph.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__vllm-static.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__vllm.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__eager.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__vllm-cudagraph.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__vllm-static.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__vllm.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3-4b__eager.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3-4b__vllm-cudagraph.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3-4b__vllm-static.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3-4b__vllm.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__eager.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__vllm-cudagraph.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__vllm-static.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__vllm.json +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results-latest.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/run_all.sh +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/run_bench.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/workloads.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/AGENT_INTEGRATION.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/ARCHITECTURE_QUIRKS.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/COMPATIBILITY.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/ENGINE_HOOK_MAPPINGS.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/GRADIENTS.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/INTERNALS.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/PERFORMANCE.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/PORTING.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/README.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/SUPPORTED_POINTS.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/USAGE.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/docs/VALIDATING_A_NEW_MODEL.md +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/__init__.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/_loop.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/address.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/arch.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/attn_config.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/attn_scores.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/autograd_support.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/capture.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/chat_compose.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/chat_conventions.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/chat_formatters.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/cuda_preflight.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/dispatch.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/facts.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/hooks.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/lens.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/load.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/mappers.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/memory.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/model.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/moe_routing.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/notebook_stdout.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/points.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/protocol.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/residual_basis.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/sampling.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/select.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/steer.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/steer_specs.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/sync.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/tokenize.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_backend.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/__init__.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/_demux.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/_hooks.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/_payload.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/_tp.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/_tree.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/attn.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/capture.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/graphs.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/lens/__init__.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/lens/intervene.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/lens/readout.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/lens/unembed.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/mhc.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_capture/native.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/interp_engine/vllm_plugin.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/conftest.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/harness.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/model_expectations.yaml +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/synthetic_families.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_address.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_attn_config_tripwire.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_attn_probs_indexing.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_attn_scores.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_attn_z_gqa.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_autograd_support.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_bench_workloads.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_capability_refusals.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_capture_addressing.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_chat_compose.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_chat_formatters.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_chat_templates.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_core.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_cuda_preflight.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_doc_code_fences.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_eager_autograd.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_facts.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_family_points.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_gated_attn_out.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_gpu_sizer.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_head_contributions.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_hook_call_conventions.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_injected_system_spans.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_layer_kinds.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_load.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_logit_transform.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_mappers.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_memory.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_mlp_internals.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_model_expectations.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_moe.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_multigpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_multimodal_arch.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_new_models_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_no_chat_template.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_normalized_hook.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_notebook_stdout.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_packaging.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_parity_gpt2.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_per_layer_attn_dims.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_points_registry.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_protocol.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_published_benchmarks.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_qk_norm.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_qkv_layout.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_reasoning_spans.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_release.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_resid_mid.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_residual_basis.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_sampling.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_sandwich_norms.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_select.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_sliding_window_attn.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_small_models_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_static_dsv4_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_static_parity_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_static_set.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_static_warmup.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_steer_context.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_sync_loop.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_sync_parity.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_unified_free_functions.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_unresolved_families.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_capture_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_capture_scales.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_engine_loop.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_graph_path.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_graphs_on_gpu.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_hook_availability.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_kv_isolation.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_new_points.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_only_families.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_plugin.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vllm_wire_grammar.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_vocabulary_boundary.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_worker_lens_capture_readout.py +0 -0
- {interp_engine-1.11.2 → interp_engine-1.11.3}/tests/test_worker_lens_readout.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: interp-engine
|
|
3
|
-
Version: 1.11.
|
|
3
|
+
Version: 1.11.3
|
|
4
4
|
Summary: A fast, standardized, and easy to use interpretability engine.
|
|
5
5
|
Project-URL: Homepage, https://github.com/decoderesearch/interp-engine
|
|
6
6
|
Project-URL: Repository, https://github.com/decoderesearch/interp-engine
|
|
@@ -65,7 +65,7 @@ from interp_engine.vllm_capture.capture import worker_addresses
|
|
|
65
65
|
from interp_engine.vllm_capture.graphs import graph_debug, refuse_writes_reason
|
|
66
66
|
from interp_engine.vllm_capture.lens import _make_lens_modifier
|
|
67
67
|
from interp_engine.vllm_capture.mhc import mhc_taps, require_available, require_steerable
|
|
68
|
-
from interp_engine.vllm_capture.steering import
|
|
68
|
+
from interp_engine.vllm_capture.steering import _compose_modifiers, _make_steer_modifiers
|
|
69
69
|
|
|
70
70
|
# --- the per-request combined hook body ---------------------------------------
|
|
71
71
|
|
|
@@ -679,9 +679,11 @@ def worker_register_steering(
|
|
|
679
679
|
demux.registered.add(req_id)
|
|
680
680
|
mods = demux.steer_mods.setdefault(req_id, {})
|
|
681
681
|
skip_set = {int(i) for i in (skip_positions or [])}
|
|
682
|
+
by_site: dict[Address, list[dict]] = {}
|
|
682
683
|
for s in specs:
|
|
683
|
-
|
|
684
|
-
|
|
684
|
+
by_site.setdefault(_write_site(worker, s), []).append(s)
|
|
685
|
+
for site, group in by_site.items():
|
|
686
|
+
mods[site] = (_make_steer_modifiers(group, demux.dev, demux.dt), skip_set, int(prompt_len))
|
|
685
687
|
_ensure_hook(worker, demux, site)
|
|
686
688
|
|
|
687
689
|
|
|
@@ -708,10 +710,12 @@ def worker_register_lens(
|
|
|
708
710
|
demux.registered.add(req_id)
|
|
709
711
|
lm = demux.lens_mods.setdefault(req_id, {})
|
|
710
712
|
skip_set = {int(i) for i in (skip_positions or [])}
|
|
713
|
+
by_site: dict[Address, list[dict]] = {}
|
|
711
714
|
for s in specs:
|
|
712
|
-
|
|
715
|
+
by_site.setdefault(_write_site(worker, s), []).append(s)
|
|
716
|
+
for site, group in by_site.items():
|
|
713
717
|
lm[site] = (
|
|
714
|
-
_make_lens_modifier(s, demux.dev, demux.dt),
|
|
718
|
+
_compose_modifiers([_make_lens_modifier(s, demux.dev, demux.dt) for s in group]),
|
|
715
719
|
bool(steer_generated),
|
|
716
720
|
skip_set,
|
|
717
721
|
int(prompt_len),
|
|
@@ -1812,9 +1812,9 @@ def worker_set_static_delta(
|
|
|
1812
1812
|
) -> None:
|
|
1813
1813
|
"""Install static writes from worker specs. Zeros every write site first.
|
|
1814
1814
|
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
forward (breakable ``add_eager``). ``lens_scope`` is the jlens
|
|
1815
|
+
A site of only plain adds, with no lens scope, fills the static ``delta`` buffer with their
|
|
1816
|
+
sum. Any other op attaches one live ``modify`` for the site's ops, in order, that reads the
|
|
1817
|
+
residual each forward (breakable ``add_eager``). ``lens_scope`` is the jlens skip.
|
|
1818
1818
|
|
|
1819
1819
|
A ``stream`` disqualifies the static buffer too. The buffer is added whole to a ``[tokens,
|
|
1820
1820
|
streams, width]`` activation, so it has no way to say "this stream and not the others"; taking
|
|
@@ -1827,59 +1827,78 @@ def worker_set_static_delta(
|
|
|
1827
1827
|
if static is None:
|
|
1828
1828
|
raise RuntimeError("set_static_delta: this worker has no static wraps")
|
|
1829
1829
|
worker_clear_static_delta(worker)
|
|
1830
|
-
|
|
1831
|
-
|
|
1830
|
+
for site, group in _group_by_site(static, specs).items():
|
|
1831
|
+
assert site.delta is not None
|
|
1832
|
+
constant = _constant_delta(group, site.delta.device, site.delta.dtype) if lens_scope is None else None
|
|
1833
|
+
if constant is not None:
|
|
1834
|
+
site.delta.copy_(constant.expand_as(site.delta))
|
|
1835
|
+
site.delta_set = True
|
|
1836
|
+
continue
|
|
1837
|
+
site.modify = _group_modifier(group, site.delta.device, site.delta.dtype)
|
|
1838
|
+
site.lens_scope = dict(lens_scope) if lens_scope else None
|
|
1839
|
+
|
|
1832
1840
|
|
|
1841
|
+
def _group_by_site(static: StaticState, specs: list[dict]) -> dict[_Site, list[dict]]:
|
|
1842
|
+
"""``specs`` per write site, in order, each op checked against what a static tap can serve."""
|
|
1843
|
+
out: dict[_Site, list[dict]] = {}
|
|
1833
1844
|
for spec in specs:
|
|
1834
1845
|
op = str(spec.get("op", SteerMethod.ADDITIVE))
|
|
1835
1846
|
if op not in STATIC_WRITE_OPS:
|
|
1836
1847
|
raise ValueError(f"static taps cannot serve op={op!r}; supported ops are {sorted(STATIC_WRITE_OPS)}")
|
|
1837
|
-
site = _write_site(static, Address(str(spec
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1848
|
+
site = _write_site(static, Address(str(spec.get("point") or "resid_post"), int(spec["layer"])))
|
|
1849
|
+
out.setdefault(site, []).append(spec)
|
|
1850
|
+
return out
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
def _constant_delta(group: list[dict], device: torch.device, dtype: torch.dtype) -> torch.Tensor | None:
|
|
1854
|
+
"""The ``[1, width]`` sum of ``group``'s deltas when every op is a plain add; else ``None``.
|
|
1855
|
+
|
|
1856
|
+
A constant vector broadcasts over a stream axis and so cannot exclude one: a ``stream`` has to
|
|
1857
|
+
go the modifier way.
|
|
1858
|
+
"""
|
|
1859
|
+
if any(
|
|
1860
|
+
str(s.get("op", SteerMethod.ADDITIVE)) != SteerMethod.ADDITIVE or s.get("stream") is not None for s in group
|
|
1861
|
+
):
|
|
1862
|
+
return None
|
|
1863
|
+
total = sum(torch.tensor(s["vector"], dtype=torch.float32, device=device) * float(s["coeff"]) for s in group)
|
|
1864
|
+
return torch.as_tensor(total).to(dtype=dtype).reshape(1, -1)
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
def _group_modifier(group: list[dict], device: torch.device, dtype: torch.dtype):
|
|
1868
|
+
"""One ``modify`` for every op in ``group``, steer and lens ops alike, applied in order."""
|
|
1869
|
+
from interp_engine.vllm_capture.lens.intervene import _make_lens_modifier
|
|
1870
|
+
from interp_engine.vllm_capture.steering import _compose_modifiers, _make_steer_modifier
|
|
1871
|
+
|
|
1872
|
+
return _compose_modifiers(
|
|
1873
|
+
[
|
|
1874
|
+
_make_lens_modifier(s, device, dtype)
|
|
1875
|
+
if str(s.get("op", SteerMethod.ADDITIVE)) in _LENS_OPS
|
|
1876
|
+
else _make_steer_modifier(s, device, dtype)
|
|
1877
|
+
for s in group
|
|
1878
|
+
]
|
|
1879
|
+
)
|
|
1851
1880
|
|
|
1852
1881
|
|
|
1853
1882
|
def _compile_write_req(
|
|
1854
|
-
|
|
1883
|
+
group: list[dict],
|
|
1855
1884
|
site: _Site,
|
|
1856
1885
|
*,
|
|
1857
1886
|
skip_positions: tuple[int, ...],
|
|
1858
1887
|
prompt_len: int,
|
|
1859
1888
|
steer_generated: bool,
|
|
1860
1889
|
) -> _WriteReq:
|
|
1861
|
-
op = str(spec.get("op", SteerMethod.ADDITIVE))
|
|
1862
|
-
if op not in STATIC_WRITE_OPS:
|
|
1863
|
-
raise ValueError(f"static taps cannot serve op={op!r}; supported ops are {sorted(STATIC_WRITE_OPS)}")
|
|
1864
1890
|
assert site.delta is not None
|
|
1865
1891
|
device, dtype = site.delta.device, site.delta.dtype
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
if op == SteerMethod.ADDITIVE and spec.get("stream") is None:
|
|
1869
|
-
vec = torch.tensor(spec["vector"], dtype=torch.float32, device=device)
|
|
1870
|
-
vec = (vec * float(spec["coeff"])).to(dtype=dtype).reshape(1, -1)
|
|
1892
|
+
constant = _constant_delta(group, device, dtype)
|
|
1893
|
+
if constant is not None:
|
|
1871
1894
|
return _WriteReq(
|
|
1872
|
-
vector=
|
|
1895
|
+
vector=constant,
|
|
1873
1896
|
skip_positions=skip_positions,
|
|
1874
1897
|
prompt_len=prompt_len,
|
|
1875
1898
|
steer_generated=steer_generated,
|
|
1876
1899
|
)
|
|
1877
|
-
from interp_engine.vllm_capture.lens.intervene import _make_lens_modifier
|
|
1878
|
-
from interp_engine.vllm_capture.steering import _make_steer_modifier
|
|
1879
|
-
|
|
1880
|
-
modify = _make_lens_modifier(spec, device, dtype) if op in _LENS_OPS else _make_steer_modifier(spec, device, dtype)
|
|
1881
1900
|
return _WriteReq(
|
|
1882
|
-
modify=
|
|
1901
|
+
modify=_group_modifier(group, device, dtype),
|
|
1883
1902
|
skip_positions=skip_positions,
|
|
1884
1903
|
prompt_len=prompt_len,
|
|
1885
1904
|
steer_generated=steer_generated,
|
|
@@ -1906,10 +1925,9 @@ def worker_register_static_write(
|
|
|
1906
1925
|
length = int(lens_scope.get("prompt_len") or length)
|
|
1907
1926
|
generated = bool(lens_scope.get("steer_generated", False))
|
|
1908
1927
|
by_site: dict[str, _WriteReq] = {}
|
|
1909
|
-
for
|
|
1910
|
-
site = _write_site(static, Address(str(spec.get("point") or "resid_post"), int(spec["layer"])))
|
|
1928
|
+
for site, group in _group_by_site(static, specs).items():
|
|
1911
1929
|
by_site[format_address(site.address)] = _compile_write_req(
|
|
1912
|
-
|
|
1930
|
+
group, site, skip_positions=skip, prompt_len=length, steer_generated=generated
|
|
1913
1931
|
)
|
|
1914
1932
|
static.write_reqs[req_id] = by_site
|
|
1915
1933
|
static.registered.add(req_id)
|
|
@@ -51,6 +51,32 @@ def _one_stream(modify, stream: int):
|
|
|
51
51
|
return _modify
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def _compose_modifiers(mods: list):
|
|
55
|
+
"""One ``modify`` for every op at one site, applied in order as eager applies a layer's ops.
|
|
56
|
+
|
|
57
|
+
Each op reads the residual the ops before it wrote, and the delta returned is their sum, so a
|
|
58
|
+
site that holds one write slot still carries all of them.
|
|
59
|
+
"""
|
|
60
|
+
if len(mods) == 1:
|
|
61
|
+
return mods[0]
|
|
62
|
+
|
|
63
|
+
def _modify_all(full: torch.Tensor) -> torch.Tensor:
|
|
64
|
+
total = mods[0](full)
|
|
65
|
+
out = full + total
|
|
66
|
+
for modify in mods[1:]:
|
|
67
|
+
delta = modify(out)
|
|
68
|
+
out = out + delta
|
|
69
|
+
total = total + delta
|
|
70
|
+
return total
|
|
71
|
+
|
|
72
|
+
return _modify_all
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _make_steer_modifiers(specs: list[dict], dev, dt):
|
|
76
|
+
""":func:`_compose_modifiers` over ``specs``, which all write one site."""
|
|
77
|
+
return _compose_modifiers([_make_steer_modifier(s, dev, dt) for s in specs])
|
|
78
|
+
|
|
79
|
+
|
|
54
80
|
def _make_steer_modifier(spec: dict, dev, dt):
|
|
55
81
|
"""Return ``modify(full_resid) -> delta`` (the tensor to ADD to the residual).
|
|
56
82
|
|
|
@@ -320,3 +320,111 @@ def test_the_worker_refuses_the_old_spelling() -> None:
|
|
|
320
320
|
_make_steer_modifier(
|
|
321
321
|
{"op": "add", "vector": _vector().tolist(), "coeff": 1.0}, torch.device("cpu"), torch.float32
|
|
322
322
|
)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
# --- several ops at one site --------------------------------------------------------------------
|
|
326
|
+
#
|
|
327
|
+
# Eager applies a layer's ops in order, each reading the residual the one before it wrote. The
|
|
328
|
+
# worker holds one write per site, so it has to fold the ops into that one write. It used to keep
|
|
329
|
+
# only the last, so two features on one layer steered with the second alone.
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _other_vector(seed: int) -> torch.Tensor:
|
|
333
|
+
return torch.randn(D_MODEL, generator=torch.Generator().manual_seed(seed))
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _three_ops_at_one_layer() -> SteeringSpec:
|
|
337
|
+
return SteeringSpec(
|
|
338
|
+
layers={
|
|
339
|
+
0: LayerSteeringSpec(
|
|
340
|
+
operations=[
|
|
341
|
+
AddSpec(vector=_other_vector(1), scale=2.0),
|
|
342
|
+
OrthogonalDecompSpec(vector=_other_vector(2), coeff=0.5),
|
|
343
|
+
ProjectionCapSpec(vector=_other_vector(3), min=None, max=0.1),
|
|
344
|
+
]
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _eager_in_order(spec: SteeringSpec, residual: torch.Tensor) -> torch.Tensor:
|
|
351
|
+
out = residual
|
|
352
|
+
for one in steering_spec_to_eager_specs(spec):
|
|
353
|
+
out = out + steer_delta(one, out, one.vector)
|
|
354
|
+
return out
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def test_ops_at_one_site_compose_on_the_worker_as_eager_applies_them() -> None:
|
|
358
|
+
from interp_engine.vllm_capture.steering import _make_steer_modifiers
|
|
359
|
+
|
|
360
|
+
spec, residual = _three_ops_at_one_layer(), _residual()
|
|
361
|
+
modify = _make_steer_modifiers(steering_spec_to_worker_specs(spec), residual.device, residual.dtype)
|
|
362
|
+
torch.testing.assert_close(residual + modify(residual), _eager_in_order(spec, residual))
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def test_one_op_at_a_site_is_its_own_modifier() -> None:
|
|
366
|
+
from interp_engine.vllm_capture.steering import _make_steer_modifiers
|
|
367
|
+
|
|
368
|
+
spec = {"op": "orthogonal", "vector": _vector().tolist(), "coeff": 0.5}
|
|
369
|
+
residual = _residual()
|
|
370
|
+
torch.testing.assert_close(
|
|
371
|
+
_make_steer_modifiers([spec], residual.device, residual.dtype)(residual), _worker_delta(spec, residual)
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def test_plain_adds_at_a_static_site_are_summed_into_one_constant() -> None:
|
|
376
|
+
from interp_engine.vllm_capture.static import _constant_delta
|
|
377
|
+
|
|
378
|
+
a, b = _other_vector(1), _other_vector(2)
|
|
379
|
+
group = [
|
|
380
|
+
{"op": "additive", "vector": a.tolist(), "coeff": 2.0},
|
|
381
|
+
{"op": "additive", "vector": b.tolist(), "coeff": -1.0},
|
|
382
|
+
]
|
|
383
|
+
got = _constant_delta(group, torch.device("cpu"), torch.float32)
|
|
384
|
+
assert got is not None
|
|
385
|
+
torch.testing.assert_close(got[0], a * 2.0 - b)
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
@pytest.mark.parametrize(
|
|
389
|
+
"extra",
|
|
390
|
+
[
|
|
391
|
+
{"op": "orthogonal", "vector": [1.0] * D_MODEL, "coeff": 0.5},
|
|
392
|
+
{"op": "additive", "vector": [1.0] * D_MODEL, "coeff": 1.0, "stream": 0},
|
|
393
|
+
],
|
|
394
|
+
)
|
|
395
|
+
def test_a_static_site_with_any_other_op_or_a_stream_needs_the_modifier(extra: dict) -> None:
|
|
396
|
+
from interp_engine.vllm_capture.static import _constant_delta
|
|
397
|
+
|
|
398
|
+
plain = {"op": "additive", "vector": [1.0] * D_MODEL, "coeff": 1.0}
|
|
399
|
+
assert _constant_delta([plain, extra], torch.device("cpu"), torch.float32) is None
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _static_worker(rows: int):
|
|
403
|
+
"""A worker with one static write site at ``resid_post.0``, and nothing else."""
|
|
404
|
+
from types import SimpleNamespace
|
|
405
|
+
|
|
406
|
+
from interp_engine.address import Address
|
|
407
|
+
from interp_engine.vllm_capture.static import StaticState, _Site
|
|
408
|
+
|
|
409
|
+
site = _Site(Address("resid_post", 0), delta=torch.zeros(rows, D_MODEL))
|
|
410
|
+
return SimpleNamespace(_ie_static=StaticState(writes={"resid_post.0": site}), model_runner=None), site
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@pytest.mark.parametrize("static_path", ["per_request", "global"])
|
|
414
|
+
def test_ops_at_one_static_site_compose_as_eager_applies_them(static_path: str) -> None:
|
|
415
|
+
from interp_engine.vllm_capture.static import (
|
|
416
|
+
_apply_write,
|
|
417
|
+
worker_register_static_write,
|
|
418
|
+
worker_set_static_delta,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
spec, residual = _three_ops_at_one_layer(), _residual()
|
|
422
|
+
specs = [{**s, "point": "resid_post"} for s in steering_spec_to_worker_specs(spec)]
|
|
423
|
+
worker, site = _static_worker(residual.shape[0])
|
|
424
|
+
if static_path == "per_request":
|
|
425
|
+
worker_register_static_write(worker, "r", specs)
|
|
426
|
+
else:
|
|
427
|
+
worker_set_static_delta(worker, specs)
|
|
428
|
+
hidden = residual.clone()
|
|
429
|
+
_apply_write(hidden, None, site, residual.shape[0], fused=False, worker=worker)
|
|
430
|
+
torch.testing.assert_close(hidden, _eager_in_order(spec, residual))
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""Several steer ops at one site: vLLM against eager, hooked and static.
|
|
2
|
+
|
|
3
|
+
Eager applies a layer's ops in order. The vLLM worker holds one write per site, and used to keep
|
|
4
|
+
only the last op there, so two features on one layer steered with the second alone. Hooked and
|
|
5
|
+
static vLLM agreed with each other, so a hooked-vs-static parity check could not see it: the
|
|
6
|
+
reference here is eager.
|
|
7
|
+
|
|
8
|
+
Two vLLM engines cannot share this process (static sets ``VLLM_USE_BREAKABLE_CUDAGRAPH``
|
|
9
|
+
process-wide), so hooked runs first, then shuts down, then static.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
import gc
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
import torch
|
|
19
|
+
from harness import require_vllm
|
|
20
|
+
|
|
21
|
+
from interp_engine.address import Address
|
|
22
|
+
|
|
23
|
+
require_vllm()
|
|
24
|
+
|
|
25
|
+
pytestmark = [
|
|
26
|
+
pytest.mark.gpu,
|
|
27
|
+
pytest.mark.skipif(not torch.cuda.is_available(), reason="the vLLM backend initializes on CUDA"),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
MODEL = "openai-community/gpt2"
|
|
31
|
+
PROMPT = "The capital of France is Paris, and the capital of Germany is"
|
|
32
|
+
MID = Address("resid_post", 6)
|
|
33
|
+
DOWN = Address("resid_post", 9)
|
|
34
|
+
COSINE_MIN = 0.999
|
|
35
|
+
LOAD_KW = {"dtype": "float32", "max_model_len": 512, "gpu_memory_utilization": 0.2}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _vector(width: int, seed: int, norm: float) -> torch.Tensor:
|
|
39
|
+
v = torch.randn(width, generator=torch.Generator().manual_seed(seed))
|
|
40
|
+
return v / v.norm() * norm
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _specs(width: int) -> dict:
|
|
44
|
+
from interp_engine.steer_specs import (
|
|
45
|
+
AddSpec,
|
|
46
|
+
LayerSteeringSpec,
|
|
47
|
+
OrthogonalDecompSpec,
|
|
48
|
+
ProjectionCapSpec,
|
|
49
|
+
SteeringSpec,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def at_mid(*ops) -> SteeringSpec:
|
|
53
|
+
return SteeringSpec(layers={int(MID.layer): LayerSteeringSpec(operations=list(ops))}, point="resid_post")
|
|
54
|
+
|
|
55
|
+
a, b, c = _vector(width, 1, 60.0), _vector(width, 2, 60.0), _vector(width, 3, 1.0)
|
|
56
|
+
return {
|
|
57
|
+
# All plain adds: the static constant path.
|
|
58
|
+
"adds": at_mid(AddSpec(vector=a, scale=1.0), AddSpec(vector=b, scale=1.0)),
|
|
59
|
+
# An op that reads the residual: the static modifier path.
|
|
60
|
+
"mixed": at_mid(
|
|
61
|
+
AddSpec(vector=a, scale=1.0),
|
|
62
|
+
OrthogonalDecompSpec(vector=c, coeff=0.0),
|
|
63
|
+
ProjectionCapSpec(vector=b, min=None, max=-5.0),
|
|
64
|
+
),
|
|
65
|
+
"last_add_only": at_mid(AddSpec(vector=b, scale=1.0)),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _cpu(captures: dict[Address, torch.Tensor]) -> torch.Tensor:
|
|
70
|
+
return captures[DOWN].detach().float().cpu()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _min_cosine(a: torch.Tensor, b: torch.Tensor) -> float:
|
|
74
|
+
assert a.shape == b.shape, f"{tuple(a.shape)} vs {tuple(b.shape)}"
|
|
75
|
+
return float(torch.nn.functional.cosine_similarity(a, b, dim=-1).min())
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.fixture(scope="module")
|
|
79
|
+
def loop():
|
|
80
|
+
"""One event loop for the module -- AsyncLLM dies if asyncio.run closes the loop."""
|
|
81
|
+
made = asyncio.new_event_loop()
|
|
82
|
+
asyncio.set_event_loop(made)
|
|
83
|
+
yield made
|
|
84
|
+
asyncio.set_event_loop(None)
|
|
85
|
+
made.close()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@pytest.fixture(scope="module")
|
|
89
|
+
def runs(loop):
|
|
90
|
+
from transformers import AutoTokenizer
|
|
91
|
+
|
|
92
|
+
from interp_engine import load_model
|
|
93
|
+
|
|
94
|
+
tokens = list(AutoTokenizer.from_pretrained(MODEL)(PROMPT)["input_ids"])
|
|
95
|
+
|
|
96
|
+
eager = load_model(MODEL, backend="eager", dtype="float32", device="cuda")
|
|
97
|
+
specs = _specs(int(eager.d_model))
|
|
98
|
+
want = {k: _cpu(loop.run_until_complete(eager.capture(tokens, [DOWN], steering_spec=s))) for k, s in specs.items()}
|
|
99
|
+
eager = None
|
|
100
|
+
gc.collect()
|
|
101
|
+
torch.cuda.empty_cache()
|
|
102
|
+
|
|
103
|
+
async def _vllm(model) -> dict:
|
|
104
|
+
return {k: _cpu(await model.capture(tokens, [DOWN], steering_spec=specs[k])) for k in ("adds", "mixed")}
|
|
105
|
+
|
|
106
|
+
hooked = load_model(MODEL, backend="vllm", **LOAD_KW)
|
|
107
|
+
loop.run_until_complete(hooked.warmup())
|
|
108
|
+
hooked_out = loop.run_until_complete(_vllm(hooked))
|
|
109
|
+
loop.run_until_complete(hooked.shutdown())
|
|
110
|
+
hooked = None
|
|
111
|
+
gc.collect()
|
|
112
|
+
torch.cuda.empty_cache()
|
|
113
|
+
|
|
114
|
+
static = load_model(MODEL, backend="vllm-static", static_points=[DOWN], static_writes=[MID], **LOAD_KW)
|
|
115
|
+
loop.run_until_complete(static.warmup())
|
|
116
|
+
try:
|
|
117
|
+
static_out = loop.run_until_complete(_vllm(static))
|
|
118
|
+
finally:
|
|
119
|
+
loop.run_until_complete(static.shutdown())
|
|
120
|
+
return {"eager": want, "hooked": hooked_out, "static": static_out}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_the_reference_would_see_a_dropped_op(runs) -> None:
|
|
124
|
+
"""Keeping only the last op moves the downstream residual well past the tolerance."""
|
|
125
|
+
assert _min_cosine(runs["eager"]["adds"], runs["eager"]["last_add_only"]) < 0.99
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@pytest.mark.parametrize("backend", ["hooked", "static"])
|
|
129
|
+
@pytest.mark.parametrize("spec", ["adds", "mixed"])
|
|
130
|
+
def test_every_op_at_a_site_applies_as_on_eager(runs, backend: str, spec: str) -> None:
|
|
131
|
+
worst = _min_cosine(runs[backend][spec], runs["eager"][spec])
|
|
132
|
+
assert worst >= COSINE_MIN, f"{backend} {spec}: min cosine {worst:.6f} against eager"
|
|
@@ -1385,10 +1385,10 @@ def test_a_static_additive_steer_confined_to_one_stream_does_not_take_the_consta
|
|
|
1385
1385
|
|
|
1386
1386
|
site = _Site(Address("resid_streams", 0), delta=torch.zeros(8, HC_MULT, D_MODEL))
|
|
1387
1387
|
spec = {"op": "additive", "vector": [1.0] * D_MODEL, "coeff": 1.0}
|
|
1388
|
-
plain = _compile_write_req(spec, site, skip_positions=(), prompt_len=0, steer_generated=True)
|
|
1388
|
+
plain = _compile_write_req([spec], site, skip_positions=(), prompt_len=0, steer_generated=True)
|
|
1389
1389
|
assert plain.vector is not None and plain.modify is None, "no stream is still the constant path"
|
|
1390
1390
|
|
|
1391
|
-
scoped = _compile_write_req({**spec, "stream": 2}, site, skip_positions=(), prompt_len=0, steer_generated=True)
|
|
1391
|
+
scoped = _compile_write_req([{**spec, "stream": 2}], site, skip_positions=(), prompt_len=0, steer_generated=True)
|
|
1392
1392
|
assert scoped.vector is None and scoped.modify is not None
|
|
1393
1393
|
delta = scoped.modify(torch.zeros(TOKENS, HC_MULT, D_MODEL))
|
|
1394
1394
|
torch.testing.assert_close(delta[:, 2, :], torch.ones(TOKENS, D_MODEL))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__eager.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/deepseek-v4-flash-0731__vllm.json
RENAMED
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__vllm-cudagraph.json
RENAMED
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/gemma-2-2b__vllm-static.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__vllm-cudagraph.json
RENAMED
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/llama-3.1-8b__vllm-static.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3-4b__vllm-cudagraph.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__vllm-cudagraph.json
RENAMED
|
File without changes
|
{interp_engine-1.11.2 → interp_engine-1.11.3}/benchmarks/results/qwen3.8-27b__vllm-static.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|