Where it lives: main (latent) and feature/granite-turboctc-default (manifests). Found at ef43e69.
tests/unit/test_asr.py::_patched_pipeline does not restore transformers.pipeline. It nests two patches:
with (
mock.patch("transformers.pipelines.pipeline", factory),
mock.patch("transformers.pipeline", factory),
):
transformers is a _LazyModule, so transformers.pipeline resolves through __getattr__, which reads it from transformers.pipelines while the outer patch is still active and caches the Mock. On exit the inner patch restores the Mock rather than the real function.
Reproduced locally (transformers 5.8.1):
in __dict__ after: False | is the mock: False
later `from transformers import pipeline` -> mock: True
tests/unit/ runs before the integration tiers, so every later real ASR load in the same session gets the stale Mock, whose side_effect is the granite_speech5_ctc ValueError from TestUnsupportedArchitectureError. Our own guard converts that into:
ImportError: transformers 5.16.0 cannot load the ASR model 'ibm-granite/granite-speech-5.0-470m-turboctc': its architecture requires transformers>=5.16
which is a false diagnosis — pods serving on transformers 5.16 transcribe correctly. This is the most damaging part: it misattributes unrelated failures to a version problem that does not exist.
Impact: 4 failures + 4 errors on the TurboCTC branch (tests/integration/test_asr_ctc_default_gpu.py, test_audio_serving_smoke[granite-4.0-micro-*]). Latent on main, which has no real CTC load to poison.
Fix: patch transformers.pipeline before transformers.pipelines.pipeline, or force the lazy resolve before patching. Add a regression test asserting the attribute is restored after the context manager exits.
Where it lives:
main(latent) andfeature/granite-turboctc-default(manifests). Found atef43e69.tests/unit/test_asr.py::_patched_pipelinedoes not restoretransformers.pipeline. It nests two patches:transformersis a_LazyModule, sotransformers.pipelineresolves through__getattr__, which reads it fromtransformers.pipelineswhile the outer patch is still active and caches the Mock. On exit the inner patch restores the Mock rather than the real function.Reproduced locally (transformers 5.8.1):
tests/unit/runs before the integration tiers, so every later real ASR load in the same session gets the stale Mock, whoseside_effectis thegranite_speech5_ctcValueError fromTestUnsupportedArchitectureError. Our own guard converts that into:which is a false diagnosis — pods serving on transformers 5.16 transcribe correctly. This is the most damaging part: it misattributes unrelated failures to a version problem that does not exist.
Impact: 4 failures + 4 errors on the TurboCTC branch (
tests/integration/test_asr_ctc_default_gpu.py,test_audio_serving_smoke[granite-4.0-micro-*]). Latent onmain, which has no real CTC load to poison.Fix: patch
transformers.pipelinebeforetransformers.pipelines.pipeline, or force the lazy resolve before patching. Add a regression test asserting the attribute is restored after the context manager exits.