Skip to content

[None][feat] Add trtllm weight loading metrics#15993

Open
yijingl-nvidia wants to merge 8 commits into
NVIDIA:mainfrom
yijingl-nvidia:weight_loading_metrics
Open

[None][feat] Add trtllm weight loading metrics#15993
yijingl-nvidia wants to merge 8 commits into
NVIDIA:mainfrom
yijingl-nvidia:weight_loading_metrics

Conversation

@yijingl-nvidia

@yijingl-nvidia yijingl-nvidia commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Description

  • Add following metrics to measure model weight loading time
    • checkpoint_preparation_seconds
    • weight_population_seconds
    • post_load_processing_seconds
    • total_model_loading_seconds
  • Add comments for parallel weight loading code

Test Coverage

Add a small unit test for the API of weight loading metrics in base LLM class. The exact weight generation code is not unit tested as it will be very slow.

Tested on clusters for TinyLlama and GLM-5 and /server_info end point returns the correct weight loading metrics.

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

Summary by CodeRabbit

  • New Features

    • Added startup metrics reporting across model loading, executors, and API responses.
    • Server info now includes startup timing details, and benchmark reports can optionally include them.
    • Exposed startup metrics through the public LLM interface for easier inspection.
  • Bug Fixes

    • Improved weight-loading flow and handling for model checkpoints, including clearer support for special cases and skipped modules.
    • Reduced the chance of missing or inconsistent timing data during load and post-load steps.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR modernizes type annotations across weight-mapper/loader classes and refactors related weight-loading control flow, and introduces a startup-metrics feature that tracks model-loading timings in ModelLoader and exposes them through executors, RPC proxies, the LLM API, the OpenAI server, and benchmark reports.

Changes

Weight mapping/loading type annotation modernization

Layer / File(s) Summary
BaseWeightMapper typed contracts and helpers
tensorrt_llm/_torch/models/checkpoints/base_weight_mapper.py
Internal fields, init_model_and_config, map_weights, apply_callbacks, properties, and helper methods (preprocess_weights, rename_by_params_map, handle_manual_copy, filter_weights, etc.) are retyped with modern generics and Mapping[str, torch.Tensor].
HF weight loader and mapper typing
tensorrt_llm/_torch/models/checkpoints/hf/weight_loader.py, tensorrt_llm/_torch/models/checkpoints/hf/weight_mapper.py
load_weights, _load_safetensors_file, apply_callbacks, _duplicate_kv_weights, and _duplicate_kv gain explicit typed signatures and expanded docstrings without logic changes.
modeling_utils load_weights typing and loading refactor
tensorrt_llm/_torch/models/modeling_utils.py
load_weights parameter typing is updated; _load_weights_impl_v2's load_single_module is restructured with early returns, mapping-based lookups, a linear_attn.conv1d squeeze, and unified consumed-weight marking.
MoE load balancer typing and loader comment
tensorrt_llm/_torch/modules/fused_moe/moe_load_balancer.py, tensorrt_llm/_torch/pyexecutor/model_engine.py
maybe_create_moe_load_balancer return type updated to AbstractContextManager; explanatory comment added before checkpoint load.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Startup metrics feature

Layer / File(s) Summary
ModelLoader timing metrics infrastructure
tensorrt_llm/_torch/models/modeling_utils.py, tensorrt_llm/_torch/pyexecutor/model_loader.py
New timing_metric context manager and ModelLoaderMetricNames enum; ModelLoader gains a _metrics dict and metrics property, with load()/_load_inner() recording total, weight-population, and post-load processing durations.
Executor-layer get_startup_metrics propagation
tensorrt_llm/executor/base_worker.py, tensorrt_llm/executor/executor.py, tensorrt_llm/executor/proxy.py, tensorrt_llm/executor/ray_executor.py, tensorrt_llm/executor/rpc_proxy.py
get_startup_metrics() added to BaseWorker, GenerationExecutor, GenerationExecutorProxy, RayExecutor, and GenerationExecutorRpcProxy, collecting rank-0 model-loader metrics via direct call or RPC with {} fallbacks.
LLM API property and server exposure
tensorrt_llm/llmapi/llm.py, tensorrt_llm/serve/openai_server.py, tests/unittest/llmapi/test_llm.py
BaseLLM.startup_metrics lazily caches metrics from the executor; OpenAIServer.get_server_info includes startup_metrics in its response; new test verifies caching behavior.
Benchmark report integration
tensorrt_llm/bench/benchmark/low_latency.py, tensorrt_llm/bench/benchmark/throughput.py, tensorrt_llm/bench/dataclasses/reporting.py
Benchmarks capture llm.startup_metrics when report_json is set and pass it to ReportUtility, which stores and conditionally includes it in get_statistics_dict().

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ModelLoader
  participant BaseWorker
  participant GenerationExecutorProxy
  participant BaseLLM
  participant OpenAIServer

  ModelLoader->>ModelLoader: record timing metrics during load
  BaseWorker->>ModelLoader: read model_loader.metrics
  GenerationExecutorProxy->>BaseWorker: get_startup_metrics() via RPC
  BaseLLM->>GenerationExecutorProxy: startup_metrics property (cached)
  OpenAIServer->>BaseLLM: read startup_metrics
  OpenAIServer-->>OpenAIServer: include startup_metrics in /server_info response
Loading

Suggested reviewers: yuxianq, pengbowang-nv, jieli-matrix, reasonsolo, hyukn

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the main change and follows the required [None][feat] summary pattern.
Description check ✅ Passed The description includes the required Description, Test Coverage, and PR Checklist sections with relevant details.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 5

🧹 Nitpick comments (8)
tensorrt_llm/_torch/models/checkpoints/base_weight_mapper.py (3)

256-277: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Docstring typo: duplicated method name.

"Subclasses opt into this path by overriding is_special_instance_module and is_special_instance_module" repeats the same name twice; the second reference should be handle_special_instance_module.

📝 Fix
-        Only call this if `self.is_special_instance_module()` returns true.
-        Subclasses opt into this path by overriding `is_special_instance_module` and
-        `is_special_instance_module`. This hook is for special modules who cannot be
+        Only call this if `self.is_special_instance_module()` returns true.
+        Subclasses opt into this path by overriding `is_special_instance_module` and
+        `handle_special_instance_module`. This hook is for special modules who cannot be
         handled by `does_require_special_handling()` and `apply_callbacks()`.
🤖 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/_torch/models/checkpoints/base_weight_mapper.py` around lines
256 - 277, The docstring for handle_special_instance_module contains a
duplicated method reference in the “Subclasses opt into this path...” sentence.
Update that sentence so the second duplicated is_special_instance_module
reference points to the correct hook name, handle_special_instance_module,
keeping the rest of the docstring unchanged.

34-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Type the Callable element in _callbacks.

list[Callable] doesn't specify the callback's expected signature. Callbacks are called as callback(module, source_name, fw) and must return a weight dict (see HfWeightMapper._duplicate_kv_weights), so this can be made precise.

As per coding guidelines, "Prefer specifying argument types in Callable type hints in e.g. Callable[[int], int] instead of Callable[..., int]."

♻️ Suggested typing
-        self._callbacks: list[Callable] = []
+        self._callbacks: list[Callable[
+            [nn.Module, str, dict[str, torch.Tensor]], dict[str, torch.Tensor]]] = []
🤖 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/_torch/models/checkpoints/base_weight_mapper.py` around lines 34
- 47, The `_callbacks` field in `BaseWeightMapper.__init__` is typed too broadly
as `list[Callable]`; update it to use a precise `Callable` signature matching
how callbacks are invoked in the mapper. Use the call pattern in
`HfWeightMapper._duplicate_kv_weights` and `BaseWeightMapper`’s callback usage
to specify the expected arguments `(module, source_name, fw)` and the returned
weight-dict type, so the type hint accurately reflects the contract.

Source: Coding guidelines


48-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

_tp_size is never initialized in __init__.

self._tp_size is only assigned in init_model_and_config, so any code path that touches self._tp_size (e.g. HfWeightMapper._duplicate_kv_weights via self._tp_size) before initialization raises AttributeError instead of failing predictably.

As per coding guidelines, "Initialize all externally visible members of a class in the constructor."

♻️ Suggested fix
     def __init__(self):
         self._callbacks: list[Callable] = []
         ...
         self._model: nn.Module | DecoderModelForCausalLM | None = None
         self._config: ModelConfig | None = None
+        self._tp_size: int = 1
🤖 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/_torch/models/checkpoints/base_weight_mapper.py` around lines 48
- 73, The mapper’s `_tp_size` member is not initialized until
`init_model_and_config`, so any access before that can raise `AttributeError`;
initialize `_tp_size` in the constructor of `BaseWeightMapper` (and any related
mapper base class) to a safe default, then keep `init_model_and_config`
responsible for updating it from `model.model_config.mapping`. Make sure code
paths such as `HfWeightMapper._duplicate_kv_weights` can rely on `_tp_size`
always existing.

Source: Coding guidelines

tensorrt_llm/_torch/models/checkpoints/hf/weight_mapper.py (1)

130-137: 🎯 Functional Correctness | 🔵 Trivial

Known latent bug documented but left unresolved.

The comment acknowledges repeat_interleave produces the wrong element order for bias duplication under tensor parallelism, currently masked because attention modules have no bias. Since this is called out explicitly as a bug, consider filing a tracking issue so it isn't lost when a bias-carrying attention module is added.

Want me to draft a fix (e.g. using torch.repeat_interleave on the head-grouped view or unsqueeze+expand+reshape, matching the 2D weight path) or open a tracking issue for this?

🤖 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/_torch/models/checkpoints/hf/weight_mapper.py` around lines 130
- 137, The bias-handling branch in weight_mapper.py’s mapping logic still
contains a documented latent bug in the `weight.ndim == 1` path, where
`repeat_interleave` produces the wrong duplication order for tensor parallelism.
Since this is intentionally left unresolved in `weight_mapper.py` (the same
branch that handles bias duplication), add a tracking issue or TODO reference
from this location so the bug is not lost, and make sure the note clearly points
to the 1D bias path for future follow-up.
tensorrt_llm/_torch/pyexecutor/model_loader.py (2)

402-411: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update load() docstring's Returns section for the new tuple return type.

The Returns section still says "The loaded and initialized PyTorch model," but the signature now returns tuple[DecoderModelForCausalLM, MoeLoadBalancer | None]. As per coding guidelines, "Always annotate functions with return types" and use Google-style docstrings that stay accurate.

🤖 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/_torch/pyexecutor/model_loader.py` around lines 402 - 411, The
load() docstring in model_loader.py still describes a single model return, but
the method now returns a tuple from DecoderModelForCausalLM and MoeLoadBalancer
| None. Update the Returns section to match the actual tuple return type and
describe both elements clearly, keeping the Google-style docstring aligned with
the load() signature and related symbols.

Source: Coding guidelines


494-499: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add stacklevel to warnings.warn.

Static analysis (B028) flags the missing stacklevel, which would otherwise point the warning at this internal helper instead of the caller.

🛠️ Proposed fix
                             warnings.warn(
                                 f"A weight tensor of shape {t.shape} is already allocated on CUDA device before "
                                 f"the weight allocation stage. This will cause extra CUDA memory usage in the "
-                                f"'{memory_type_map[self.model_weights_memory_tag]}' scope."
+                                f"'{memory_type_map[self.model_weights_memory_tag]}' scope.",
+                                stacklevel=2,
                             )
🤖 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/_torch/pyexecutor/model_loader.py` around lines 494 - 499, The
warning emitted in the weight allocation path is missing a stacklevel, so it
will point to the internal helper instead of the caller. Update the
warnings.warn call in model_loader.py to include an appropriate stacklevel so
the warning is attributed to the external caller while keeping the existing
message and context around the preallocated CUDA weight tensor.

Source: Linters/SAST tools

tensorrt_llm/bench/dataclasses/reporting.py (1)

394-410: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a small unit test for startup_metrics inclusion in get_statistics_dict().

No test currently covers that get_statistics_dict() conditionally includes startup_metrics based on truthiness. A quick test (e.g., in a tests/unittest/bench reporting test module, if one exists) would guard this JSON contract against regression.

🤖 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/bench/dataclasses/reporting.py` around lines 394 - 410, Add a
focused unit test for get_statistics_dict in reporting.py that verifies
startup_metrics is conditionally included only when the field is truthy and
omitted when it is falsy. Use the ReportingStats or equivalent class setup that
exercises self.startup_metrics and assert the returned stats_dict JSON contract
for both cases, ideally in the existing bench reporting test module if
available.
tests/unittest/llmapi/test_llm.py (1)

2712-2746: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Coverage: sufficient for the caching contract; consider two follow-up cases.

Good targeted test for the primary caching behavior. Coverage could be extended (not blocking) in tests/unittest/llmapi/test_llm.py with:

  • A case where generator._executor is None, asserting startup_metrics returns {} without caching a stale empty dict permanently.
  • A case in tests/unittest/serve (or similar) verifying OpenAIServer.get_server_info's getattr(..., "startup_metrics", {}) fallback when generator lacks the attribute entirely.

As per path instructions, "Act as a QA engineer reviewing test changes and coverage for TensorRT-LLM... suggest concrete list file names and whether coverage is sufficient, insufficient, or needs follow-up outside the PR."

🤖 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 `@tests/unittest/llmapi/test_llm.py` around lines 2712 - 2746, The new test
covers the main caching path, but follow up by adding two cases: one for
BaseLLM.get_startup_metrics when _executor is None to verify it returns an empty
dict without permanently caching stale state, and one for
OpenAIServer.get_server_info to verify the getattr(generator, "startup_metrics",
{}) fallback when the generator has no startup_metrics attribute. Use the
existing test_startup_metrics_are_cached_and_reported_by_server_info setup as
the reference point and keep the assertions focused on cache behavior and the
server-info response shape.

Source: Path instructions

🤖 Prompt for all review comments with 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.

Inline comments:
In `@tensorrt_llm/_torch/models/modeling_utils.py`:
- Around line 690-695: The `load_weights` annotation uses a quoted
`BaseWeightMapper` forward reference, but the symbol is not available to static
analyzers. Update `tensorrt_llm/_torch/models/modeling_utils.py` so
`BaseWeightMapper` is imported or referenced under a `TYPE_CHECKING` guard in
the same module, keeping the `load_weights` signature intact while making
Ruff/mypy able to resolve the name.
- Around line 690-695: The load_weights method currently uses a mutable default
for skip_modules, which can leak state across calls if it is ever modified
directly. Update the load_weights signature and body so skip_modules is not a
shared list default, and initialize it at the start of the function with a safe
fallback before it is passed into add_skip_modules or any other helper.
- Around line 1175-1177: Move the zero-parameter early return in
`load_module_weights` so special-instance modules are handled first. The current
`len(module._parameters) == 0` check returns before
`handle_special_instance_module()` can run, which skips MoE wrapper types like
`LagunaMoE`, `Qwen3MoE`, and `AfmoeMoE` that implement
`is_special_instance_module()`. Update the control flow around
`weight_mapper.should_skip_module`, `is_special_instance_module()`, and
`handle_special_instance_module()` so special modules are processed even when
they have no direct parameters, and only then apply the zero-parameter skip for
normal modules.

In `@tensorrt_llm/_torch/pyexecutor/model_loader.py`:
- Around line 412-421: The TOTAL_MODEL_LOADING_SECONDS metric currently starts
after _load_and_validate_config(), so it misses config parsing, default
application, and validation. Update ModelLoader.load() so the timing_metric
around ModelLoaderMetricNames.TOTAL_MODEL_LOADING_SECONDS.value covers the
entire load flow, including _load_and_validate_config() and the subsequent
_load_inner() call. Keep the config computed only once, and preserve the
existing maybe_create_moe_load_balancer() handling inside the same overall
timing scope.

In `@tensorrt_llm/serve/openai_server.py`:
- Around line 2019-2025: The get_server_info async route is doing a potentially
blocking startup_metrics lookup through self.generator, which can stall the
event loop on the first /server_info call. Update get_server_info to avoid
calling the RPC-backed property directly on the async path by either reading a
prepopulated cache from generator or offloading the lookup to a
non-blocking/background mechanism before serving traffic. Keep the
disaggregated_params response unchanged and make sure startup_metrics is
obtained without invoking RPCClient._call_sync() inside this request handler.

---

Nitpick comments:
In `@tensorrt_llm/_torch/models/checkpoints/base_weight_mapper.py`:
- Around line 256-277: The docstring for handle_special_instance_module contains
a duplicated method reference in the “Subclasses opt into this path...”
sentence. Update that sentence so the second duplicated
is_special_instance_module reference points to the correct hook name,
handle_special_instance_module, keeping the rest of the docstring unchanged.
- Around line 34-47: The `_callbacks` field in `BaseWeightMapper.__init__` is
typed too broadly as `list[Callable]`; update it to use a precise `Callable`
signature matching how callbacks are invoked in the mapper. Use the call pattern
in `HfWeightMapper._duplicate_kv_weights` and `BaseWeightMapper`’s callback
usage to specify the expected arguments `(module, source_name, fw)` and the
returned weight-dict type, so the type hint accurately reflects the contract.
- Around line 48-73: The mapper’s `_tp_size` member is not initialized until
`init_model_and_config`, so any access before that can raise `AttributeError`;
initialize `_tp_size` in the constructor of `BaseWeightMapper` (and any related
mapper base class) to a safe default, then keep `init_model_and_config`
responsible for updating it from `model.model_config.mapping`. Make sure code
paths such as `HfWeightMapper._duplicate_kv_weights` can rely on `_tp_size`
always existing.

In `@tensorrt_llm/_torch/models/checkpoints/hf/weight_mapper.py`:
- Around line 130-137: The bias-handling branch in weight_mapper.py’s mapping
logic still contains a documented latent bug in the `weight.ndim == 1` path,
where `repeat_interleave` produces the wrong duplication order for tensor
parallelism. Since this is intentionally left unresolved in `weight_mapper.py`
(the same branch that handles bias duplication), add a tracking issue or TODO
reference from this location so the bug is not lost, and make sure the note
clearly points to the 1D bias path for future follow-up.

In `@tensorrt_llm/_torch/pyexecutor/model_loader.py`:
- Around line 402-411: The load() docstring in model_loader.py still describes a
single model return, but the method now returns a tuple from
DecoderModelForCausalLM and MoeLoadBalancer | None. Update the Returns section
to match the actual tuple return type and describe both elements clearly,
keeping the Google-style docstring aligned with the load() signature and related
symbols.
- Around line 494-499: The warning emitted in the weight allocation path is
missing a stacklevel, so it will point to the internal helper instead of the
caller. Update the warnings.warn call in model_loader.py to include an
appropriate stacklevel so the warning is attributed to the external caller while
keeping the existing message and context around the preallocated CUDA weight
tensor.

In `@tensorrt_llm/bench/dataclasses/reporting.py`:
- Around line 394-410: Add a focused unit test for get_statistics_dict in
reporting.py that verifies startup_metrics is conditionally included only when
the field is truthy and omitted when it is falsy. Use the ReportingStats or
equivalent class setup that exercises self.startup_metrics and assert the
returned stats_dict JSON contract for both cases, ideally in the existing bench
reporting test module if available.

In `@tests/unittest/llmapi/test_llm.py`:
- Around line 2712-2746: The new test covers the main caching path, but follow
up by adding two cases: one for BaseLLM.get_startup_metrics when _executor is
None to verify it returns an empty dict without permanently caching stale state,
and one for OpenAIServer.get_server_info to verify the getattr(generator,
"startup_metrics", {}) fallback when the generator has no startup_metrics
attribute. Use the existing
test_startup_metrics_are_cached_and_reported_by_server_info setup as the
reference point and keep the assertions focused on cache behavior and the
server-info response shape.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 49f92af6-ec79-4fe1-ad68-4ceef9ffad27

📥 Commits

Reviewing files that changed from the base of the PR and between 011e849 and 6ae0972.

📒 Files selected for processing (18)
  • tensorrt_llm/_torch/models/checkpoints/base_weight_mapper.py
  • tensorrt_llm/_torch/models/checkpoints/hf/weight_loader.py
  • tensorrt_llm/_torch/models/checkpoints/hf/weight_mapper.py
  • tensorrt_llm/_torch/models/modeling_utils.py
  • tensorrt_llm/_torch/modules/fused_moe/moe_load_balancer.py
  • tensorrt_llm/_torch/pyexecutor/model_engine.py
  • tensorrt_llm/_torch/pyexecutor/model_loader.py
  • tensorrt_llm/bench/benchmark/low_latency.py
  • tensorrt_llm/bench/benchmark/throughput.py
  • tensorrt_llm/bench/dataclasses/reporting.py
  • tensorrt_llm/executor/base_worker.py
  • tensorrt_llm/executor/executor.py
  • tensorrt_llm/executor/proxy.py
  • tensorrt_llm/executor/ray_executor.py
  • tensorrt_llm/executor/rpc_proxy.py
  • tensorrt_llm/llmapi/llm.py
  • tensorrt_llm/serve/openai_server.py
  • tests/unittest/llmapi/test_llm.py

Comment thread tensorrt_llm/_torch/models/modeling_utils.py
Comment thread tensorrt_llm/_torch/models/modeling_utils.py
Comment thread tensorrt_llm/_torch/pyexecutor/model_loader.py Outdated
Comment thread tensorrt_llm/serve/openai_server.py Outdated
@leslie-fang25
leslie-fang25 removed their request for review July 7, 2026 04:41
"""
return self._mapping

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just checking: do we want it to be the actual handle, or do we want to do a shallow copy with dict(self._mapping)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Sorry that this is existing code, not added by me. I changed the function definition order to better align with how those functions are used in the weight loading function, but it seems it adds trouble to code reviewing. I will revert the function order in the next version of the PR.

weights: dict) -> dict:
@property
def skip_modules(self) -> list[str]:
return self._skip_modules

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Similar question here re shallow copy.

) and model.config.head_dim is not None else model.config.hidden_size // model.config.num_attention_heads
return head_dim

def preprocess_weights(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I know this isn't related to your change per se, but I'm curious why we need both this and rename_by_params_map? It almost sounds like we should get rid of the latter, and have its implementation be the default in this method that children can override.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I think this class has been modified by many engineers, adding somewhat overlapping functionalities. We can certainly clean up the implementation in future.

def should_skip_module(self, module_name: str) -> bool:
return any(skip_module in module_name
for skip_module in self._skip_modules)
def handle_manual_copy(self,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I find the change a bit hard to follow since many methods existed before, but just had their docstrings enhanced, but moved to other parts of the file. The diffs make it hard to know what exactly was changed and what wasn't. Any way we could get the bots to minimize the diff by having the methods closer to the original lines changed? That way it also makes merge conflicts less annoying to resolve.

@yijingl-nvidia yijingl-nvidia Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Totally agree! I will revert the function order change.

Comment thread tensorrt_llm/_torch/models/modeling_utils.py
@yijingl-nvidia

Copy link
Copy Markdown
Collaborator Author

@2ez4bz I've reverted the function order change. This should be now easier to review. Feel free to give any more feedbacks

@yijingl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #60795 [ run ] triggered by Bot. Commit: 4b7da49 Link to invocation

Comment on lines +634 to +638
with timing_metric(
ModelLoaderMetricNames.WEIGHT_POPULATION_SECONDS.
value, self._metrics):
self._call_load_weights(model.load_weights, weights,
self.weight_mapper)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

IIUC This timer stops as soon as _call_load_weights() returns, but multiple loaders enqueue non_blocking=True copies or kernels without waiting. The only stream synchronization is later inside the post_load_processing_seconds scope, so the reported population value undercounts those loads and charges their asynchronous tail to post-load processing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. I've updated the PR to address this by calling torch.cuda.synchronize() after every weight loading and post processing timing section.

Comment on lines +949 to +951
with timing_metric(
ModelLoaderMetricNames.POST_LOAD_PROCESSING_SECONDS.value,
self._metrics):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For both GMS roles (RO and RW), post_load_apply() and the remaining post-load or materialization steps execute above, after which gms_post_load_handled becomes True. By the time this timing context starts, it skips all of that work and records only MoE finalization, synchronization, and empty_cache(). Consequently, post_load_processing_seconds can be materially wrong for GMS RW and RO.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for showing me the GMS's special post load handling logic. Without a doc to explain how GMS code works (e.g. what R0 and RW means), I could not fix the timing measure for GMS on my own. Can you help me find out where to add the post load processing timing measure for GMS?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've spent some time familiarizing myself with GMS and let Codex address the GMS post load timing issue. I have updated the PR. Can you take a look again?

@chienchunhung

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #60795 [ run ] completed with state SUCCESS. Commit: 4b7da49
/LLM/main/L0_MergeRequest_PR pipeline #49073 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
Signed-off-by: Yijing Li <257409031+yijingl-nvidia@users.noreply.github.com>
@yijingl-nvidia
yijingl-nvidia force-pushed the weight_loading_metrics branch from 6cd3a43 to 41805dd Compare July 26, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants