Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
34 changes: 34 additions & 0 deletions tensorrt_llm/tokenizer/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,38 @@ def _fallback_to_fast_tokenizer(pretrained_model_dir: str,
**merged)


def _resolve_missing_local_path_to_hf_hub_id(pretrained_model_dir: str) -> str:
"""Rewrite a nonexistent absolute path to a matching HF Hub repo id.

Transformers 5.x's tightened ``validate_repo_id`` rejects strings with
more than one ``/`` before the Hub lookup can fall back, so absolute
filesystem paths that no longer exist now raise ``HFValidationError``
instead of resolving from the cache as they did in 4.x. When the local
HF cache holds exactly one model repo whose basename matches, rewrite
to that repo id; otherwise return unchanged so the original error path
is preserved.
"""
if not os.path.isabs(pretrained_model_dir) or os.path.isdir(
pretrained_model_dir):
return pretrained_model_dir
Comment on lines +165 to +167

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not use isdir() as the missing-path check.

os.path.isdir() is false for existing regular files, so an absolute file can be rewritten when its basename matches a cached model. Use os.path.lexists() (or exists() if broken symlinks should count as missing) to preserve every existing path.

Proposed fix
-    if not os.path.isabs(pretrained_model_dir) or os.path.isdir(
+    if not os.path.isabs(pretrained_model_dir) or os.path.lexists(
             pretrained_model_dir):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not os.path.isabs(pretrained_model_dir) or os.path.isdir(
pretrained_model_dir):
return pretrained_model_dir
if not os.path.isabs(pretrained_model_dir) or os.path.lexists(
pretrained_model_dir):
return pretrained_model_dir
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/tokenizer/tokenizer.py` around lines 165 - 167, Update the path
check in the tokenizer’s pretrained-model directory resolution logic to use
os.path.lexists() instead of os.path.isdir(), preserving any existing absolute
path including regular files and symlinks while retaining the current handling
for non-absolute paths.

basename = os.path.basename(pretrained_model_dir.rstrip("/"))
if not basename:
return pretrained_model_dir
from huggingface_hub import scan_cache_dir
from huggingface_hub.utils import CacheNotFound
try:
cache_info = scan_cache_dir()
except CacheNotFound:
return pretrained_model_dir
Comment on lines +171 to +176

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tokenizer.py context =="
sed -n '145,190p' tensorrt_llm/tokenizer/tokenizer.py

echo
echo "== search for scan_cache_dir usage =="
rg -n "scan_cache_dir|CacheNotFound" tensorrt_llm -S

echo
echo "== Hugging Face cache docs/source references in repo =="
rg -n "huggingface_hub|cache dir|scan_cache_dir" -S README* docs tensorrt_llm || true

Repository: NVIDIA/TensorRT-LLM

Length of output: 8001


🌐 Web query:

huggingface_hub scan_cache_dir ValueError cache path is a file documented behavior

💡 Result:

Yes, the ValueError "cache path is a file" is a documented behavior of the scan_cache_dir function in the huggingface_hub library [1][2]. When you call scan_cache_dir, the library performs a validation check on the provided cache directory path. If the path specified exists but points to a file instead of a directory, the function explicitly raises a ValueError with a message indicating that it expects a directory but found a file [3]. This behavior is documented in the official Hugging Face documentation under the Cache-system reference [1][2]. The documentation explicitly states under the "Raises" section for scan_cache_dir that a ValueError will be thrown if the cache directory is a file rather than a directory [1][2]. The underlying implementation uses Python's pathlib.Path.is_file method to perform this check before proceeding with the scan [3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import inspect, sys
try:
    import huggingface_hub
    from huggingface_hub import scan_cache_dir
    from huggingface_hub.utils import CacheNotFound
    print("huggingface_hub version:", getattr(huggingface_hub, "__version__", "unknown"))
    print("scan_cache_dir:", scan_cache_dir)
    print("CacheNotFound:", CacheNotFound)
    print("scan_cache_dir doc:")
    print(inspect.getdoc(scan_cache_dir) or "<no doc>")
except Exception as e:
    print("IMPORT_ERROR:", type(e).__name__, e)
PY

Repository: NVIDIA/TensorRT-LLM

Length of output: 225


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import inspect
try:
    import huggingface_hub
    from huggingface_hub import scan_cache_dir
    from huggingface_hub.utils import CacheNotFound
    print("huggingface_hub version:", getattr(huggingface_hub, "__version__", "unknown"))
    print("scan_cache_dir:", scan_cache_dir)
    print("CacheNotFound:", CacheNotFound)
    print("scan_cache_dir doc:")
    print(inspect.getdoc(scan_cache_dir) or "<no doc>")
except Exception as e:
    print("IMPORT_ERROR:", type(e).__name__, e)
PY

Repository: NVIDIA/TensorRT-LLM

Length of output: 225


Catch ValueError from scan_cache_dir(). It also raises when the cache path exists but is a file, so falling back to pretrained_model_dir keeps AutoTokenizer on the existing error path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/tokenizer/tokenizer.py` around lines 171 - 176, Update the cache
lookup around scan_cache_dir() to also catch ValueError and return
pretrained_model_dir, preserving the existing CacheNotFound fallback and
AutoTokenizer error path.

matches = [
repo.repo_id for repo in cache_info.repos if repo.repo_type == "model"
and repo.repo_id.rsplit("/", 1)[-1] == basename
]
if len(matches) == 1:
return matches[0]
return pretrained_model_dir


def maybe_fix_byte_level_tokenizer(tokenizer, pretrained_model_dir: str,
**kwargs):
"""Work around Transformers 5.x LlamaTokenizer overriding tokenizer.json.
Expand Down Expand Up @@ -285,6 +317,8 @@ def __repr__(self) -> str:

@classmethod
def from_pretrained(cls, pretrained_model_dir: str, **kwargs):
pretrained_model_dir = _resolve_missing_local_path_to_hf_hub_id(
pretrained_model_dir)
Comment on lines +320 to +321

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant tokenizer code.
python3 - <<'PY'
from pathlib import Path

path = Path("tensorrt_llm/tokenizer/tokenizer.py")
lines = path.read_text().splitlines()
for start, end in [(140, 190), (300, 340)]:
    print(f"\n--- {path}:{start}-{end} ---")
    for i in range(start, end + 1):
        if i <= len(lines):
            print(f"{i:4d}: {lines[i-1]}")
PY

# Look for cache_dir handling in this file.
rg -n "cache_dir|scan_cache_dir|from_pretrained|_resolve_missing_local_path_to_hf_hub_id" tensorrt_llm/tokenizer/tokenizer.py

# If the Python packages are available, print the relevant API signatures/docs.
python3 - <<'PY'
import inspect

for mod_name, obj_name in [
    ("huggingface_hub", "scan_cache_dir"),
    ("transformers", "AutoTokenizer"),
]:
    try:
        mod = __import__(mod_name, fromlist=[obj_name])
        obj = getattr(mod, obj_name)
        print(f"\n--- {mod_name}.{obj_name} ---")
        if obj_name == "AutoTokenizer":
            print("from_pretrained signature:", inspect.signature(obj.from_pretrained))
        else:
            print("signature:", inspect.signature(obj))
    except Exception as e:
        print(f"\n--- {mod_name}.{obj_name} unavailable ---")
        print(type(e).__name__, e)
PY

Repository: NVIDIA/TensorRT-LLM

Length of output: 6659


🌐 Web query:

huggingface_hub scan_cache_dir cache_dir parameter documentation

💡 Result:

The scan_cache_dir function in the huggingface_hub library is used to programmatically scan your Hugging Face cache directory [1][2]. The function accepts an optional parameter named cache_dir [1][3]: - Parameter: cache_dir - Type: str, Path, or None [2][4] - Description: Specifies the path to the cache directory you wish to scan [1][3]. - Default: If this parameter is not provided (or set to None), the function defaults to the standard Hugging Face cache directory [1][4]. When called, scan_cache_dir returns an HFCacheInfo structure containing a detailed report of the contents of the specified directory, organized by repositories, revisions, and files [1][5]. If a repository is found to be corrupted, the function handles the error internally and includes a CorruptedCacheException in the report's warnings rather than crashing [1][2].

Citations:


Pass the caller cache_dir through the resolver

tensorrt_llm/tokenizer/tokenizer.py:320-321 forwards kwargs to AutoTokenizer.from_pretrained(), but _resolve_missing_local_path_to_hf_hub_id() still scans the default Hugging Face cache at tensorrt_llm/tokenizer/tokenizer.py:171-174. In custom-cache setups, this can rewrite to the wrong repo id when the same basename exists in multiple caches. Pass kwargs.get("cache_dir") into the helper and call scan_cache_dir(cache_dir=cache_dir).

📍 Affects 1 file
  • tensorrt_llm/tokenizer/tokenizer.py#L320-L321 (this comment)
  • tensorrt_llm/tokenizer/tokenizer.py#L171-L174
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/tokenizer/tokenizer.py` around lines 320 - 321, The resolver
currently ignores the caller’s custom cache directory, which can select the
wrong repository. Update _resolve_missing_local_path_to_hf_hub_id and its call
site around pretrained_model_dir to accept kwargs.get("cache_dir"), then pass
that value to scan_cache_dir(cache_dir=cache_dir). Apply the changes at
tensorrt_llm/tokenizer/tokenizer.py lines 320-321 and 171-174.

try:
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_dir,
**kwargs)
Expand Down
2 changes: 0 additions & 2 deletions tests/integration/test_lists/waives.txt
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,6 @@ unittest/llmapi/test_additional_model_outputs.py -m "gpu2" SKIP (https://nvbugs/
unittest/llmapi/test_additional_model_outputs.py::test_additional_model_outputs_integration_pp2 SKIP (https://nvbugs/6427411)
unittest/llmapi/test_llm.py::test_llm_with_customized_tokenizer SKIP (https://nvbugs/6507080)
unittest/llmapi/test_llm.py::test_openai_completion_list_prompt_stream_reuses_stream_metadata SKIP (https://nvbugs/6507081)
unittest/llmapi/test_llm.py::test_tokenizer_decode_incrementally[/scratch.trt_llm_data/llm-models/falcon-7b-instruct-False-0.95-HF] SKIP (https://nvbugs/6507082)
unittest/llmapi/test_llm.py::test_tokenizer_decode_incrementally[/scratch.trt_llm_data/llm-models/falcon-7b-instruct-False-0.95-TRTLLM] SKIP (https://nvbugs/6507082)
unittest/llmapi/test_llm_multi_gpu_pytorch.py -m "gpu2" SKIP (https://nvbugs/6428092)
unittest/llmapi/test_llm_multi_gpu_pytorch.py::test_llm_get_stats_pp2[False-False-True] SKIP (https://nvbugs/6432826)
unittest/llmapi/test_llm_multi_gpu_pytorch.py::test_llm_get_stats_pp4[False-False-True] SKIP (https://nvbugs/6427411)
Expand Down
Loading