Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion demos/Grokking_Demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,18 @@
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"DeprecationWarning:\n",
"\n",
"HookedTransformer is deprecated and will be removed in 4.0. Use TransformerBridge.boot_transformers(...) instead, then call enable_compatibility_mode() for HookedTransformer-equivalent numerics.\n",
"\n"
]
}
],
"source": [
"model = HookedTransformer(cfg)"
]
Expand Down
13 changes: 12 additions & 1 deletion demos/No_Position_Experiment.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,18 @@
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"DeprecationWarning:\n",
"\n",
"HookedTransformer is deprecated and will be removed in 4.0. Use TransformerBridge.boot_transformers(...) instead, then call enable_compatibility_mode() for HookedTransformer-equivalent numerics.\n",
"\n"
]
}
],
"source": [
"cfg = HookedTransformerConfig(\n",
" n_layers=2,\n",
Expand Down
13 changes: 12 additions & 1 deletion demos/Othello_GPT.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,18 @@
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [],
"outputs": [

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grokking_Demo.ipynb and No_Position_Experiment.ipynb also construct HookedTransformer(cfg) in cells with empty stored outputs, and both run under make notebook-test. Can their outputs be re-recorded as well?

{
"name": "stderr",
"output_type": "stream",
"text": [
"DeprecationWarning:\n",
"\n",
"HookedTransformer is deprecated and will be removed in 4.0. Use TransformerBridge.boot_transformers(...) instead, then call enable_compatibility_mode() for HookedTransformer-equivalent numerics.\n",
"\n"
]
}
],
"source": [
"import transformer_lens.utilities as utils\n",
"\n",
Expand Down
4 changes: 4 additions & 0 deletions demos/doc_sanitize.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ replace: \1
[regex6d]
regex: (0\.[1-9]\d{2})\d+
replace: \1
[regex7]
regex: [^\n]*DeprecationWarning:(?=\n\nHookedTransformer is deprecated and will be removed in 4\.0\. Use TransformerBridge\.boot_transformers\(\.\.\.\) instead, then call enable_compatibility_mode\(\) for HookedTransformer-equivalent numerics\.)
replace: DeprecationWarning:
105 changes: 105 additions & 0 deletions tests/unit/test_deprecation_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""Regression coverage for deprecated legacy entry points."""

from __future__ import annotations

import importlib
import subprocess
import sys
import warnings
from pathlib import Path

import pytest

PROJECT_ROOT = Path(__file__).parents[2]


def _small_config():
from transformer_lens import HookedTransformerConfig

return HookedTransformerConfig(
n_layers=1,
d_model=16,
d_head=4,
n_heads=4,
n_ctx=8,
d_vocab=20,
attn_only=True,
)


def _assert_single_deprecation(constructor, class_name: str) -> None:
with pytest.warns(DeprecationWarning, match=class_name) as caught:
constructor()

assert len(caught) == 1
assert "TransformerBridge.boot_transformers" in str(caught[0].message)
assert "4.0" in str(caught[0].message)


def test_importing_transformer_lens_emits_no_deprecation_warning():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the time this body runs, transformer_lens is already in sys.modules, so the import is a no-op that records nothing. I appended a real import-time DeprecationWarning to __init__.py and this test still passed. Is there a way to check import-time cleanliness that would fail?

code = "\n".join(
[
"import warnings",
"warnings.filterwarnings(",
" 'error',",
" category=DeprecationWarning,",
" module=r'^transformer_lens(?:\\.|$)',",
")",
"import transformer_lens",
]
)
result = subprocess.run(
[sys.executable, "-c", code],
capture_output=True,
cwd=PROJECT_ROOT,
text=True,
check=False,
)

assert result.returncode == 0, result.stderr


def test_hooked_transformer_constructor_warns_once():
from transformer_lens import HookedTransformer

_assert_single_deprecation(lambda: HookedTransformer(_small_config()), "HookedTransformer")


def test_hooked_encoder_constructor_warns_once():
from transformer_lens import HookedEncoder

_assert_single_deprecation(lambda: HookedEncoder(_small_config()), "HookedEncoder")


def test_hooked_encoder_from_pretrained_warns_at_callsite(monkeypatch):
hooked_encoder_module = importlib.import_module("transformer_lens.HookedEncoder")

def stop_loading(*args, **kwargs):
raise RuntimeError("stop after deprecation warning")

monkeypatch.setattr(hooked_encoder_module.loading, "get_official_model_name", stop_loading)
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("default")
with pytest.raises(RuntimeError, match="stop after deprecation warning"):
hooked_encoder_module.HookedEncoder.from_pretrained("bert-base-cased")

deprecations = [
warning for warning in caught if issubclass(warning.category, DeprecationWarning)
]
assert len(deprecations) == 1
assert "HookedEncoder.from_pretrained" in str(deprecations[0].message)
assert deprecations[0].filename == __file__


def test_bert_next_sentence_prediction_constructor_warns_once():
from transformer_lens import BertNextSentencePrediction

_assert_single_deprecation(
lambda: BertNextSentencePrediction(object()), "BertNextSentencePrediction"
)


def test_direct_hooked_root_module_construction_warns_once():
from transformer_lens import HookedRootModule

_assert_single_deprecation(HookedRootModule, "HookedRootModule")
8 changes: 8 additions & 0 deletions transformer_lens/BertNextSentencePrediction.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
to e.g. GPT style transformers.
"""

import warnings
from typing import Any, Dict, List, Optional, Tuple, Union, overload

import torch
Expand All @@ -31,6 +32,13 @@ class BertNextSentencePrediction:
"""

def __init__(self, model: Any):
warnings.warn(
"BertNextSentencePrediction is deprecated and will be removed in 4.0. Use "
"TransformerBridge.boot_transformers(...) for BERT-style models; see "
"demos/BERT.ipynb.",
DeprecationWarning,
stacklevel=2,
)
self.model = model

def __call__(
Expand Down
13 changes: 13 additions & 0 deletions transformer_lens/HookedEncoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import logging
import os
import warnings
from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union, cast, overload

import torch
Expand Down Expand Up @@ -58,6 +59,12 @@ def __init__(
**kwargs: Any,
):
super().__init__()
warnings.warn(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HookedEncoder.from_pretrained("bert-base-cased") still surfaces no deprecation notices because stacklevel=2 attributes the warning to HookedEncoder.py itself and Python's default ignore::DeprecationWarning filter then drops it. Can the warning also fire at the from_pretrained entry point, the way the sibling loaders do?

"HookedEncoder is deprecated and will be removed in 4.0. Use "
"TransformerBridge.boot_transformers(...) instead.",
DeprecationWarning,
stacklevel=2,
)
if isinstance(cfg, Dict):
cfg = HookedTransformerConfig(**cfg)
elif isinstance(cfg, str):
Expand Down Expand Up @@ -379,6 +386,12 @@ def from_pretrained(
**from_pretrained_kwargs: Any,
) -> HookedEncoder:
"""Loads in the pretrained weights from huggingface. Currently supports loading weight from HuggingFace BertForMaskedLM. Unlike HookedTransformer, this does not yet do any preprocessing on the model."""
warnings.warn(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside pytest from_pretrained sits one frame below its caller, so stacklevel=4 overshoots and CPython attributes the warning to <sys>:0 — a plain script still sees nothing, while the sibling using stacklevel=2 does surface (HookedEncoderDecoder.py:555). The depth and the filename assertion at test_deprecation_warnings.py:91 have to move together.

"HookedEncoder.from_pretrained is deprecated and will be removed in 4.0. Use "
"TransformerBridge.boot_transformers(...) instead.",
DeprecationWarning,
stacklevel=4,
)
logging.warning(
"Support for BERT in TransformerLens is currently experimental, until such a time when it has feature "
"parity with HookedTransformer and has been tested on real research tasks. Until then, backward "
Expand Down
8 changes: 8 additions & 0 deletions transformer_lens/HookedRootModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from __future__ import annotations

import logging
import warnings
from collections.abc import Callable, Iterable
from contextlib import contextmanager
from functools import partial
Expand Down Expand Up @@ -54,6 +55,13 @@ class HookedRootModule(HookIntrospectionMixin, nn.Module):

def __init__(self, *args: Any):
super().__init__()
if type(self) is HookedRootModule:
warnings.warn(
"HookedRootModule is deprecated and will be removed in 4.0. Use "
"TransformerBridge.boot_transformers(...) instead.",
DeprecationWarning,
stacklevel=2,
)
self.is_caching = False
self.context_level = 0

Expand Down
8 changes: 8 additions & 0 deletions transformer_lens/HookedTransformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import logging
import os
import warnings
from collections.abc import Generator
from typing import (
Any,
Expand Down Expand Up @@ -164,6 +165,13 @@ def __init__(
default_padding_side: Which side to pad on.
"""
super().__init__()
warnings.warn(
"HookedTransformer is deprecated and will be removed in 4.0. Use "
"TransformerBridge.boot_transformers(...) instead, then call "
"enable_compatibility_mode() for HookedTransformer-equivalent numerics.",
DeprecationWarning,
stacklevel=2,
)
if isinstance(cfg, str):
raise ValueError(
"Please pass in a config dictionary or HookedTransformerConfig object. If you want to load a "
Expand Down
Loading