import_fixes + drift detectors: cover transformers 5.x drift (#5423)
PR #5414's drift detectors and the corresponding import_fixes helpers were written against transformers 4.x. The Repo tests (CPU) step (which installs transformers>=4.51,<5.5 and currently resolves to 5.4.0) surfaces three real predicate gaps: * test_pretrained_model_enable_input_require_grads_uses_old_pattern fires DRIFT DETECTED whenever the source contains "for module in self.modules()". But the unsloth replacement that patch_enable_input_require_grads installs ALSO uses that pattern -- deliberately, just wrapped in try / except NotImplementedError. So the predicate cannot distinguish broken upstream from the working patch. Accept either pre-HF#41993 shape (no self.modules() loop) or the post-patch shape (loop + NotImplementedError handler). * test_transformers_torchcodec_available_flag_is_present asserts the pre-5.x module-level _torchcodec_available flag. transformers 5 replaced it with an lru_cache'd is_torchcodec_available() callable. Accept either symbol. Also update disable_torchcodec_if_broken to actually disable on 5.x: clear the cache and rebind the function to return False. Local verification: * transformers 4.57.6 + trl 0.25.1 + peft 0.19.1 + triton 3.5.1 + vllm 0.15.1+cu130 (the Core HF=4.57.6 cell shape): 18 passed. * transformers 5.8.1 + peft 0.19.1 + torch 2.9 CPU (the Repo tests (CPU) shape, drop trl / vllm / datasets / xformers): 12 passed, 6 skipped on missing optional libs, 0 failed. PR #5376's Repo tests (CPU) failure was a triple: - triton + enable_input_require_grads: fixed by merging current main (PR #5421's relaxed triton predicate + conftest 'import unsloth'). - torchcodec: fixed by THIS PR.
This commit is contained in:
parent
9a0d6f80cb
commit
770714acc5
2 changed files with 51 additions and 18 deletions
|
|
@ -175,10 +175,12 @@ def test_trl_cached_available_flags_are_not_tuples():
|
|||
|
||||
|
||||
def test_pretrained_model_enable_input_require_grads_uses_old_pattern():
|
||||
"""``patch_enable_input_require_grads`` (import_fixes.py 609-670).
|
||||
HF PR #41993 rewrote enable_input_require_grads to iterate
|
||||
"""``patch_enable_input_require_grads`` (import_fixes.py 609-670). HF
|
||||
PR #41993 rewrote enable_input_require_grads to iterate
|
||||
``self.modules()`` and call ``get_input_embeddings`` on every
|
||||
submodule; vision submodules then raise NotImplementedError."""
|
||||
submodule; vision submodules then raise NotImplementedError. Healthy
|
||||
state: either the upstream rewrite isn't present (pre-HF#41993), OR
|
||||
the patch installed a NotImplementedError-tolerant replacement."""
|
||||
pytest.importorskip("transformers")
|
||||
from transformers import PreTrainedModel
|
||||
|
||||
|
|
@ -187,24 +189,34 @@ def test_pretrained_model_enable_input_require_grads_uses_old_pattern():
|
|||
except Exception as exc:
|
||||
pytest.skip(f"could not getsource(enable_input_require_grads): {exc!r}")
|
||||
|
||||
if "for module in self.modules()" in src:
|
||||
pytest.fail(
|
||||
"DRIFT DETECTED: PreTrainedModel.enable_input_require_grads now "
|
||||
"iterates self.modules() (post HF#41993). "
|
||||
"patch_enable_input_require_grads has to install a "
|
||||
"NotImplementedError-tolerant replacement."
|
||||
)
|
||||
if "for module in self.modules()" not in src:
|
||||
return # healthy: pre-HF#41993 shape
|
||||
if "NotImplementedError" in src:
|
||||
return # healthy: unsloth's tolerant replacement is installed
|
||||
|
||||
pytest.fail(
|
||||
"DRIFT DETECTED: PreTrainedModel.enable_input_require_grads now "
|
||||
"iterates self.modules() (post HF#41993) and has NOT been "
|
||||
"wrapped by patch_enable_input_require_grads; vision submodules "
|
||||
"(e.g. GLM V4.6's self.visual) will raise NotImplementedError "
|
||||
"from get_input_embeddings and crash the whole call."
|
||||
)
|
||||
|
||||
|
||||
def test_transformers_torchcodec_available_flag_is_present():
|
||||
"""``disable_torchcodec_if_broken`` (import_fixes.py 1291-1317).
|
||||
Flips ``transformers.utils.import_utils._torchcodec_available`` to
|
||||
False when torchcodec is installed but its FFmpeg deps are broken."""
|
||||
"""``disable_torchcodec_if_broken`` (import_fixes.py 1291-1317). Needs
|
||||
either the pre-5.x module-level ``_torchcodec_available`` flag, or
|
||||
the 5.x ``is_torchcodec_available`` public function; one of the two
|
||||
is the patch site the fix monkey-patches when FFmpeg is missing."""
|
||||
tf_iu = pytest.importorskip("transformers.utils.import_utils")
|
||||
assert hasattr(tf_iu, "_torchcodec_available"), (
|
||||
"transformers.utils.import_utils._torchcodec_available was "
|
||||
"removed/renamed upstream; disable_torchcodec_if_broken can no "
|
||||
"longer disable a broken torchcodec install."
|
||||
has_flag = hasattr(tf_iu, "_torchcodec_available")
|
||||
has_func = callable(getattr(tf_iu, "is_torchcodec_available", None))
|
||||
assert has_flag or has_func, (
|
||||
"transformers.utils.import_utils dropped both "
|
||||
"``_torchcodec_available`` (pre-5.x) AND "
|
||||
"``is_torchcodec_available`` (>=5.x); "
|
||||
"disable_torchcodec_if_broken can no longer disable a broken "
|
||||
"torchcodec install."
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1298,6 +1298,13 @@ def disable_torchcodec_if_broken():
|
|||
|
||||
This function tests if torchcodec can actually load and if not, patches
|
||||
transformers to think torchcodec is unavailable so it falls back to librosa.
|
||||
|
||||
Two shapes to cover:
|
||||
* transformers < 5: a module-level ``_torchcodec_available`` flag
|
||||
cached in ``transformers.utils.import_utils``; flip it to False.
|
||||
* transformers >= 5: a public ``is_torchcodec_available()`` callable
|
||||
wrapped with ``functools.lru_cache``; replace it with a stub that
|
||||
returns False and clear the cache so subsequent callers see it.
|
||||
"""
|
||||
try:
|
||||
import importlib.util
|
||||
|
|
@ -1311,11 +1318,25 @@ def disable_torchcodec_if_broken():
|
|||
# torchcodec cannot load - disable it in transformers
|
||||
try:
|
||||
import transformers.utils.import_utils as tf_import_utils
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
# transformers < 5 path: module-level cached flag.
|
||||
try:
|
||||
tf_import_utils._torchcodec_available = False
|
||||
except (ImportError, AttributeError):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# transformers >= 5 path: public lru_cache'd function. Clear any
|
||||
# cached True result then rebind to a stub that returns False.
|
||||
is_avail = getattr(tf_import_utils, "is_torchcodec_available", None)
|
||||
if is_avail is not None:
|
||||
try:
|
||||
is_avail.cache_clear()
|
||||
except AttributeError:
|
||||
pass
|
||||
tf_import_utils.is_torchcodec_available = lambda: False
|
||||
|
||||
|
||||
def disable_broken_wandb():
|
||||
"""Disable wandb if it's installed but cannot actually import.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue