4.57.3 issue with AutoTokenizer.from_pretrained when HF_HUB_OFFLINE=1
Author: g8a9
Pull request: no
Labels: name: bug

### System Info

- `transformers` version: 4.57.3
- Platform: Linux-5.15.0-124-generic-x86_64-with-glibc2.35
- Python version: 3.11.11
- Huggingface_hub version: 0.36.0
- Safetensors version: 0.7.0
- Accelerate version: not installed
- Accelerate config: not found
- DeepSpeed version: not installed
- PyTorch version (accelerator?): 2.9.1+cu128 (CUDA)
- Tensorflow version (GPU?): not installed (NA)
- Flax version (CPU?/GPU?/TPU?): not installed (NA)
- Jax version: not installed
- JaxLib version: not installed
- Using distributed or parallel set-up in script?: no
- Using GPU in script?: not in the example above
- GPU type: NVIDIA RTX A6000

### Who can help?

Probably @ArthurZucker, @itazap, and @Rocketknight1 

### Reproduction

### Bug Description 

When working offline (`HF_HUB_OFFLINE=1`), AutoTokenizer.from_pretrained() fails when a standard model ID is used, and that model is already cached. The same issue does not affect AutoModel or AutoConfig. 

### Reproducing the bug

This bash script:

```bash
#!/usr/bin/env bash
set -euo pipefail

VENV_DIR="test-transformers"
REPO_ID="Qwen/Qwen2.5-0.5B"
export HF_HOME="./test_cache"

echo "[1/6] Creating uv venv: ${VENV_DIR}"
uv venv "${VENV_DIR}"

# shellcheck disable=SC1091
source "${VENV_DIR}/bin/activate"

echo "[2/6] Installing transformers==4.57.3 and torch"
uv pip install "transformers==4.57.3" torch

echo "[3/5] Downloading repo via huggingface_hub.snapshot_download: ${REPO_ID}"
REPO_ID="${REPO_ID}" python - <<'PY'
import os
from huggingface_hub import snapshot_download

repo_id = os.environ["REPO_ID"]
hf_home = os.environ["HF_HOME"]

print(f"HF_HOME={hf_home}")
path = snapshot_download(repo_id=repo_id)
print(f"snapshot_download OK: {repo_id}")
print(f"Snapshot path: {path}")
PY

echo "[4/5] Exporting HF_HUB_OFFLINE=1"
export HF_HUB_OFFLINE=1

echo "[5/5] Testing transformers from_pretrained calls (AutoConfig/AutoTokenizer/AutoModel) with repo id: ${REPO_ID}"
REPO_ID="${REPO_ID}" python - <<'PY'
import os
import sys
import traceback

repo_id = os.environ["REPO_ID"]
print(f"HF_HOME={os.environ.get('HF_HOME')}")
print(f"HF_HUB_OFFLINE={os.environ.get('HF_HUB_OFFLINE')}")

failures: list[str] = []

def run(name: str, fn) -> None:
    try:
        fn()
        print(f"{name}: OK")
    except Exception:
        tb = traceback.format_exc()
        failures.append(f"{name} FAILED:\n{tb}")
        print(f"{name}: FAILED (full traceback below)")
        print(tb)

from transformers import AutoConfig, AutoTokenizer, AutoModel

run("AutoConfig.from_pretrained", lambda: AutoConfig.from_pretrained(repo_id))
run("AutoTokenizer.from_pretrained", lambda: AutoTokenizer.from_pretrained(repo_id))
run("AutoModel.from_pretrained", lambda: AutoModel.from_pretrained(repo_id))

if failures:
    print("\n=== SUMMARY: one or more calls failed ===")
    for msg in failures:
        print(msg)
        print("-" * 80)
    sys.exit(1)

print("\nAll from_pretrained calls succeeded.")
PY
```

prints this output in the final step

```
=== SUMMARY: one or more calls failed ===
AutoTokenizer.from_pretrained FAILED:
Traceback (most recent call last):
  File "<stdin>", line 13, in run
  File "<stdin>", line 24, in <lambda>
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/models/auto/tokenization_auto.py", line 1156, in from_pretrained
    return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2113, in from_pretrained
    return cls._from_pretrained(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2395, in _from_pretrained
    tokenizer = cls._patch_mistral_regex(
                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2438, in _patch_mistral_regex
    if _is_local or is_base_mistral(pretrained_model_name_or_path):
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2432, in is_base_mistral
    model = model_info(model_id)
            ^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/utils/_validators.py", line 114, in _inner_fn
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/hf_api.py", line 2660, in model_info
    r = get_session().get(path, headers=headers, timeout=timeout, params=params)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/utils/_http.py", line 106, in send
    raise OfflineModeIsEnabled(
huggingface_hub.errors.OfflineModeIsEnabled: Cannot reach https://huggingface.co/api/models/Qwen/Qwen2.5-0.5B: offline mode is enabled. To disable it, please unset the `HF_HUB_OFFLINE` environment variable.
```

where something in `_patch_mistral_regex` or `_is_base_mistral` seems off / not respecting the HF_HUB_OFFLINE flag.

### Expected behavior

Correctly pull the tokenizers files already present on disk.

Comments:
#42914 mentions a missing chat_template, but I believe it goes beyond that.

Moreover, it seems that the same script with `"transformers==4.57.1"` does work.

Hey @g8a9, good news - this is actually already fixed on main!

The bug was in the `_patch_mistral_regex` function which called `model_info()` without checking for offline mode first. As part of a tokenizer refactoring, the code was moved to `tokenization_utils_tokenizers.py` and now correctly sets `is_local = True` when `is_offline_mode()` returns true, so the network call is skipped.

Until the next release, you can work around this by passing `local_files_only=True`:

```python
AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B", local_files_only=True)
```

I've opened #43212 to add a regression test for this.

Hey @Anri-Lombard, thanks for the quick response. In the meantime, I downgraded to 4.57.1 and will wait for the new release. 

However, for total clarity, I've tried the script again with `local_files_only=True` and the error persists.

Here is the final print (which seems identical to the first one to me):
```
=== SUMMARY: one or more calls failed ===
AutoTokenizer.from_pretrained FAILED:
Traceback (most recent call last):
  File "<stdin>", line 13, in run
  File "<stdin>", line 24, in <lambda>
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/models/auto/tokenization_auto.py", line 1156, in from_pretrained
    return tokenizer_class.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2113, in from_pretrained
    return cls._from_pretrained(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2395, in _from_pretrained
    tokenizer = cls._patch_mistral_regex(
                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2438, in _patch_mistral_regex
    if _is_local or is_base_mistral(pretrained_model_name_or_path):
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/transformers/tokenization_utils_base.py", line 2432, in is_base_mistral
    model = model_info(model_id)
            ^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/utils/_validators.py", line 114, in _inner_fn
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/hf_api.py", line 2660, in model_info
    r = get_session().get(path, headers=headers, timeout=timeout, params=params)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/scratch-artemis/giuseppe/melt-data/test-transformers/lib/python3.11/site-packages/huggingface_hub/utils/_http.py", line 106, in send
    raise OfflineModeIsEnabled(
huggingface_hub.errors.OfflineModeIsEnabled: Cannot reach https://huggingface.co/api/models/Qwen/Qwen2.5-0.5B: offline mode is enabled. To disable it, please unset the `HF_HUB_OFFLINE` environment variable.
```

#42880 should fix your issue, we will release a patch for this cc @ArthurZucker 

Thanks! Also, I'm closing this since it's basically a duplicate of #42886