HuggingFace models fail on Python 3.13: NameError from exec/eval in download_model (PEP 667)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1k
- Forks
- 346
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Every hf_* model fails to instantiate on Python 3.13 with
NameError: name '<XConfig>' is not defined, raised from
torchbenchmark/util/framework/huggingface/basic_configs.py::download_model.
python install.py fails outright, so the models cannot even be installed.
Python 3.12 and earlier are unaffected. I understand utils/python_utils.py
currently targets 3.10-3.12, so this is filed as a Python 3.13 support blocker
rather than a regression on a supported config.
Repro
conda create -n tb_py313 python=3.13 -y && conda activate tb_py313
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
git clone https://github.com/pytorch/benchmark.git && cd benchmark
python install.py --torch hf_Bert_large # already fails here
python test.py -k "test_hf_Bert_large_train_cpu" fails with the same
NameError if you force past the install.
Observed
$ python install.py --torch hf_Bert_large
checking packages numpy, torch are installed, generating constaints...OK
running setup for .../torchbenchmark/models/hf_Bert_large...FAIL
Traceback (most recent call last):
File ".../torchbenchmark/models/hf_Bert_large/install.py", line 13, in <module>
cache_model(model_name)
~~~~~~~~~~~^^^^^^^^^^^^
File ".../torchbenchmark/util/framework/huggingface/patch_hf.py", line 15, in cache_model
download_model(name)
~~~~~~~~~~~~~~^^^^^^
File ".../torchbenchmark/util/framework/huggingface/basic_configs.py", line 304, in download_model
config = eval(HUGGINGFACE_MODELS[model_name][2])
File "<string>", line 1, in <module>
NameError: name 'BertConfig' is not defined
RuntimeError: Failed to complete setup
Same failure via python test.py -k "test_hf_Bert_large_train_cpu"
torchbenchmark._components._impl.workers.subprocess_rpc.ChildTraceException: Traceback (most recent call last):
File ".../torchbenchmark/_components/_impl/workers/subprocess_rpc.py", line 510, in _run_block
exec(compile(cmd, "<subprocess-worker>", "exec"), globals_dict) # noqa: P204
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<subprocess-worker>", line 39, in <module>
File "<subprocess-worker>", line 11, in _run_in_worker_f
File ".../torchbenchmark/util/model.py", line 43, in __call__
obj = type.__call__(cls, *args, **kwargs)
File ".../torchbenchmark/models/hf_Bert_large/__init__.py", line 11, in __init__
super().__init__(
~~~~~~~~~~~~~~~~^
name="hf_Bert_large",
^^^^^^^^^^^^^^^^^^^^^
...<3 lines>...
extra_args=extra_args,
^^^^^^^^^^^^^^^^^^^^^^
)
^
File ".../torchbenchmark/util/framework/huggingface/model_factory.py", line 51, in __init__
self.model_cls, self.model = download_model(name)
~~~~~~~~~~~~~~^^^^^^
File ".../torchbenchmark/util/framework/huggingface/basic_configs.py", line 304, in download_model
config = eval(HUGGINGFACE_MODELS[model_name][2])
File "<string>", line 1, in <module>
NameError: name 'BertConfig' is not defined
Root cause
config_cls_name = _extract_config_cls_name(HUGGINGFACE_MODELS[model_name][2])
exec(f"from transformers import {config_cls_name}")
config = eval(HUGGINGFACE_MODELS[model_name][2])
exec() with no explicit namespace binds the imported class into the snapshot
of download_model's locals. Through 3.12 that snapshot was a cached dict that
the following eval() also read from, so the name was visible. Python 3.13
implements PEP 667, where locals() in an optimized scope returns a fresh
independent snapshot per call, so the binding is discarded before eval() runs.
Minimal repro, no torch or torchbench required:
def download_model():
exec("from transformers import BertConfig")
return eval("BertConfig()")
download_model() # OK on 3.12, NameError on 3.13
This affects all entries in HUGGINGFACE_MODELS, including the AutoConfig
ones, since the config class is always exec-imported.
Suggested fix
Pass an explicit namespace to eval instead of relying on exec leaking into
locals. Works identically on 3.9-3.13:
config_cls_name = _extract_config_cls_name(HUGGINGFACE_MODELS[model_name][2])
eval_globals = {
"transformers": transformers,
config_cls_name: getattr(transformers, config_cls_name),
}
config = eval(HUGGINGFACE_MODELS[model_name][2], eval_globals)
The similar exec at extended_configs.py:41 is at module scope and is not
affected.
Happy to send a PR if that fix looks right.
Environment
- pytorch/benchmark main @ fcfbbc85817f47fddcc320ef654faf207e338d7f (2026-08-01), working tree clean
- Python 3.13.14 -> fails, Python 3.12.13 -> passes
- Same commit, same torch 2.13.0+cpu, same transformers 4.57.3 in both envs
- CPU-only, Linux x86_64 (RHEL 9.5, kernel 5.14)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in torchbenchmark/util/framework/huggingface/basic_configs.py at download_model and inspect the exec/eval sequence around line 304. Reproduce with the provided Python 3.13 install command and run python test.py -k "test_hf_Bert_large_train_cpu"; done means the model installs and the test passes on Python 3.13 without breaking the reported Python 3.12 behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- huggingface, python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100