Coverage for transformer_lens/model_bridge/sources/_driver_base.py: 100%
18 statements
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-21 19:27 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-21 19:27 +0000
1"""Optional base class for :class:`Driver` implementations.
3The protocol is duck-typed; inheriting is convenient, not required.
4"""
5from __future__ import annotations
7from abc import ABC, abstractmethod
8from typing import Any, Mapping
10from transformer_lens.config import TransformerBridgeConfig
11from transformer_lens.model_bridge.driver_protocol import (
12 ForwardResult,
13 Intervention,
14 TensorLike,
15)
18class DriverBase(ABC):
19 """Defaults for the optional Driver members. Subclasses implement ``forward``
20 and override the rest only when they can do better."""
22 architecture: str = ""
23 # The bridge overwrites this slot at construction (registry − non_fireable)
24 # when it's empty. Whitelist-semantic drivers (e.g. Inspect) declare a
25 # non-empty set in the subclass to keep it.
26 supported_hook_points: frozenset[str] = frozenset()
27 non_fireable_hook_points: frozenset[str] = frozenset()
29 # Subclasses override with the capability strings they actually serve.
30 _supported_features: frozenset[str] = frozenset()
32 # True if forward() returns logits for every position, so loss is computable.
33 # Drivers that synthesize only the final position set this False; the bridge
34 # then refuses return_type=loss/both rather than return nan.
35 provides_sequence_logits: bool = True
37 def __init__(
38 self,
39 bridge_config: TransformerBridgeConfig,
40 tokenizer: Any,
41 *,
42 architecture: str | None = None,
43 ) -> None:
44 self.bridge_config = bridge_config
45 self.tokenizer = tokenizer
46 # Resolution order: explicit kwarg > bridge_config field > class default.
47 self.architecture = (
48 architecture or getattr(bridge_config, "architecture", "") or self.architecture
49 )
51 @abstractmethod
52 def forward(
53 self,
54 input_ids: TensorLike | None = None,
55 *,
56 capture: tuple[str, ...] = (),
57 intervene: Mapping[str, Intervention] | None = None,
58 max_new_tokens: int = 1,
59 return_logits: bool = True,
60 **kwargs: Any,
61 ) -> ForwardResult:
62 ...
64 def close(self) -> None:
65 """No-op default. Override when the driver owns releasable resources."""
67 def supports(self, feature: str) -> bool:
68 return feature in self._supported_features
70 # Torch-specific surface (parameters, named_parameters, state_dict, weight
71 # access) is NOT defined here. Drivers that serve those methods provide
72 # them directly; callers route via supports("...") + hasattr/getattr.