Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
7db8244
test(vllm): cover native BF16 MoE refit lifecycle
seonjinn Aug 2, 2026
e919d26
fix(vllm): reload unquantized TRTLLM MoE weights
seonjinn Aug 2, 2026
2ce743e
fix(vllm): preserve refit error fallback
seonjinn Aug 2, 2026
b79256b
fix(vllm): default injected reload state safely
seonjinn Aug 2, 2026
e3d561d
fix(vllm): constrain native TRTLLM refit scope
seonjinn Aug 2, 2026
a81e440
test(vllm): harden native refit failure coverage
seonjinn Aug 2, 2026
d791753
test(vllm): isolate refit capability contract
seonjinn Aug 2, 2026
6009452
fix(vllm): harden native layerwise refit failures
seonjinn Aug 2, 2026
8b8d658
Merge remote-tracking branch 'origin/main' into sna/bf16-trtllm-nativ…
seonjinn Aug 7, 2026
3ea0ce5
Merge origin/main into sna/bf16-trtllm-native-refit-pr-20260807
seonjinn Aug 7, 2026
7cc62b4
Merge remote-tracking branch 'origin/main' into sna/bf16-trtllm-nativ…
seonjinn Aug 8, 2026
a73421e
fix(vllm): detect realized TRTLLM refit backend
seonjinn Aug 8, 2026
7180bff
test(vllm): use module-shaped refit fixtures
seonjinn Aug 8, 2026
809ddd6
Merge remote-tracking branch 'origin/main' into sna/bf16-trtllm-nativ…
seonjinn Aug 13, 2026
95452e9
test(vllm): address native refit self-review
seonjinn Aug 13, 2026
8881a6d
test(vllm): cover refit buffer reuse
seonjinn Aug 13, 2026
cfd6cab
test(vllm): satisfy import ordering
seonjinn Aug 13, 2026
87af15c
fix(vllm): support native BF16 TRTLLM refit
seonjinn Aug 15, 2026
4edab68
test(vllm): cover TRTLLM NCCL reshard refit
seonjinn Aug 15, 2026
06b8967
fix(vllm): support TRTLLM NCCL reshard refit
seonjinn Aug 15, 2026
2cadb92
test(vllm): preserve TRTLLM staging dtype
seonjinn Aug 15, 2026
64cbbdc
docs(vllm): clarify TRTLLM reshard staging
seonjinn Aug 15, 2026
9d5a10a
refactor(refit): expose local shard slices
seonjinn Aug 15, 2026
2844542
test(vllm): cover unsupported TRTLLM reshard layout
seonjinn Aug 15, 2026
9347077
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Aug 17, 2026
ac8e396
fix(vllm): harden TRTLLM NCCL reshard refit
seonjinn Aug 17, 2026
a84a210
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Aug 18, 2026
c119bdb
style: format TRTLLM reshard test
seonjinn Aug 18, 2026
d59a987
Merge remote-tracking branch 'origin/main' into review/pr3659-main-sy…
seonjinn Aug 18, 2026
873f52e
Merge branch 'main' into sna/bf16-trtllm-native-refit-pr-20260807
seonjinn Aug 18, 2026
f0c23ae
Merge remote-tracking branch 'origin/main' into review/pr3545-main-sy…
seonjinn Aug 18, 2026
8a3e9da
Merge upstream/main into sna/bf16-trtllm-native-refit-pr-20260807
seonjinn Aug 19, 2026
10e40a5
fix(vllm): refresh HPC state after layerwise refit
seonjinn Aug 20, 2026
6c40cfc
Merge PR 3545 foundation and latest main into BF16 TRTLLM NCCL refit
seonjinn Aug 20, 2026
cfe6e68
Merge origin/main into bf16-trtllm-nccl-reshard-refit
seonjinn Aug 26, 2026
9cc96b0
Update BF16 TRTLLM refit wording from unquantized to BF16
seonjinn Aug 26, 2026
88ff1ab
Fix nccl_reshard backend unit test fixtures for refit-info validation
seonjinn Aug 27, 2026
8a0f573
Merge remote-tracking branch 'origin/main' into sna/pr3659-main-sync-…
seonjinn Aug 29, 2026
ddf7495
fix(vllm): reuse exact shard calculation for refit
seonjinn Sep 2, 2026
d0bcb96
fix(refit): cover Qwen3.5 TRTLLM NCCL reshard
seonjinn Sep 3, 2026
8bd7eb9
Merge remote-tracking branch 'origin/main' into codex/pr3659-qwen35-r…
seonjinn Sep 3, 2026
9a5d850
docs(refit): clarify FP8 KV cache restriction
seonjinn Sep 3, 2026
621641d
refactor(refit): drop unrelated shard comments
seonjinn Sep 3, 2026
b4dd3ab
Merge remote-tracking branch 'origin/main' into codex/pr3659-qwen35-r…
seonjinn Sep 3, 2026
4e987b5
test(refit): cover padded Lightning expert staging
seonjinn Sep 3, 2026
7b3f79f
test(refit): exercise Lightning native loader input
seonjinn Sep 4, 2026
748fc71
fix(vllm): dispatch mixed TRTLLM refit by module
seonjinn Sep 4, 2026
feff039
test(vllm): cover mixed refit scope boundaries
seonjinn Sep 4, 2026
f2214aa
test(vllm): model realized MoE backend faithfully
seonjinn Sep 4, 2026
48301b6
fix(vllm): scope native reload to BF16 TRTLLM modules
seonjinn Sep 4, 2026
7c1eb09
test(vllm): target deferred reload fixture by module
seonjinn Sep 4, 2026
94a22cb
test(vllm): cover mixed FP8 transport safety
seonjinn Sep 4, 2026
6c63d5d
test(vllm): exercise refit loaders through module contracts
seonjinn Sep 4, 2026
bde0bf6
fix(vllm): preserve mixed refit loader ownership
seonjinn Sep 4, 2026
7f7b8dd
test(vllm): cover nested layer count config
seonjinn Sep 4, 2026
2de2d65
fix(vllm): resolve nested text layer counts
seonjinn Sep 4, 2026
b5d52ed
test(vllm): use normalized layer names
seonjinn Sep 4, 2026
299a357
test(vllm): cover static MTP ownership
seonjinn Sep 4, 2026
52900b8
fix(vllm): preserve static MTP drafters
seonjinn Sep 4, 2026
347b24d
test(vllm): accept remote-code model construction
seonjinn Sep 4, 2026
830a6ca
fix(mxfp8): validate mixed layer boundaries
seonjinn Sep 4, 2026
5b14cad
fix(mxfp8): validate scope before patching workers
seonjinn Sep 4, 2026
96101df
docs(fp8): explain mixed MXFP8 rollout scope
seonjinn Sep 4, 2026
8eddc45
chore: minimize Qwen3.5 TRTLLM recipe
seonjinn Sep 4, 2026
f20709b
test(vllm): update FP8 refit loader stub
seonjinn Sep 4, 2026
d8e8088
test(refit): reproduce mixed TRTLLM init ordering
seonjinn Sep 6, 2026
9326f41
fix(refit): build TRTLLM maps after communicator init
seonjinn Sep 6, 2026
d3f3f06
test(refit): cover both reshard setup orders
seonjinn Sep 6, 2026
c2f8c1f
fix(refit): support both reshard setup orders
seonjinn Sep 6, 2026
593e4eb
Merge main into BF16 TRTLLM NCCL reshard refit
seonjinn Sep 6, 2026
ad6d0dc
test(vllm): cover FP8 layerwise generator loading
seonjinn Sep 6, 2026
78d066d
docs(refit): document BF16 TRTLLM limits
seonjinn Sep 6, 2026
08d8687
fix(vllm): preserve FP8 reload iterator contents
seonjinn Sep 6, 2026
38deaed
chore(vllm): type tracked reload storage pointers
seonjinn Sep 6, 2026
7ecfc32
test(qwen3.5): exempt long model setup from idle reaper
seonjinn Sep 6, 2026
eb7529f
test(qwen3.5): align async launch topology
seonjinn Sep 6, 2026
90bbc30
fix(vllm): satisfy refit lint checks
seonjinn Sep 7, 2026
3d2d769
Merge remote-tracking branch 'upstream/main' into sna/pr3659-review-v…
seonjinn Sep 7, 2026
7dfc93a
test(vllm): cover batched BF16 TRTLLM layout
seonjinn Aug 16, 2026
7c1856a
perf(vllm): batch BF16 TRTLLM expert layout conversion
seonjinn Aug 16, 2026
1256eaa
fix(vllm): cover full TRTLLM reload lifecycle
seonjinn Aug 16, 2026
a62e3e0
fix(vllm): isolate TRTLLM reload converter by context
seonjinn Aug 16, 2026
2c2b6cd
style: format TRTLLM refit tests
seonjinn Aug 18, 2026
014a305
test(qwen3.5): enable BF16 TRTLLM nightly
seonjinn Sep 7, 2026
69698ec
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Sep 7, 2026
fecc707
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Sep 7, 2026
cecdaf8
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Sep 9, 2026
8bb95b3
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Sep 9, 2026
7126eed
Merge branch 'main' into sna/bf16-trtllm-nccl-reshard-refit-main-2026…
seonjinn Sep 9, 2026
d24868e
Merge latest PR 3659 into BF16 TRTLLM batching
seonjinn Sep 9, 2026
f1950fb
fix(vllm): defer optional FlashInfer import
seonjinn Sep 9, 2026
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
55 changes: 35 additions & 20 deletions docs/design-docs/nccl-reshard-refit.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ single `ValueError` listing every violation. The current requirements are:
`vllm_cfg.precision=fp8` and `vllm_cfg.is_mx=true`; the generation ranks
quantize each received BF16 shard before installing it. Blockwise-FP8 train →
MXFP8 gen is not supported.
* BF16 FlashInfer TRTLLM MoE is supported through vLLM's native
layerwise-reload path. Its grouped expert weights must use expert-parallel
destination sharding with linear expert placement; tensor-sharded expert
destinations and round-robin placement are rejected. This path does not
support an FP8 KV cache or a co-trained MTP drafter; setup rejects both
combinations.
* vLLM expert parallelism is supported with the NeMo RL convention
`expert_parallel_size == tensor_parallel_size`.
* Generation-side, PP > 1 is not supported.
Expand Down Expand Up @@ -67,18 +73,22 @@ nccl-reshard-refit implementation:
Two FFN-named groups are explicitly excluded and ride the misc path instead:
shared-expert weights (`*.shared_expert.*`, which fuse differently on the vLLM
side) and co-trained MTP drafter weights (which vLLM keeps in a separate
drafter module updated through `load_weights`). MTP weights are recognized two
ways: bare-`mtp.`-prefix HF names (NemotronH, Qwen3.5) via
drafter module updated through `load_weights`). Co-trained MTP is not supported
with BF16 FlashInfer TRTLLM; this routing applies to other supported backend
combinations. MTP weights are recognized two ways: bare-`mtp.`-prefix HF names
(NemotronH, Qwen3.5) via
`is_nccl_reshard_param()`, and DeepSeek-style MTP exported as trailing
`model.layers.N` indices via provenance — the Megatron-side name carries an
`mtp.` module segment (bare for LM bridges, `language_model.mtp.*` for the VL
and EXAONE bridges), so the worker excludes those HF layers when building the
metadata (`_collect_mtp_hf_layer_names()`).
* **Misc path** — everything else (embeddings, attention projections, layernorms, the
MoE router, `lm_head`, FP8 `_scale_inv` siblings, FP8 KV-cache scales, …). These ride
a packed broadcast (conventional `packed_tensor.py` implementation) over the shared
`model_update_group` and are loaded on the generation side through the backend's
regular `load_weights` machinery.
MoE router, `lm_head`, FP8 `_scale_inv` siblings, FP8 KV-cache scales, …). FP8
KV-cache scales are supported only by backend combinations that allow an FP8 KV
cache; BF16 FlashInfer TRTLLM rejects that configuration at setup. These tensors
ride a packed broadcast (conventional `packed_tensor.py` implementation) over the
shared `model_update_group` and are loaded on the generation side through the
backend's regular `load_weights` machinery.

The feature is integrated into the `nemo_rl/weight_sync/` framework:
`create_weight_synchronizer(..., nccl_reshard_refit=True)` returns a
Expand All @@ -92,8 +102,8 @@ training starts:

1. **`init_collective()`** — creates the `model_update_group`, a NCCL group spanning all
training and generation ranks. The bulk path does not use it; it carries the misc
packed-broadcast (and FP8 KV-cache scales), identical to the conventional collective
transport.
packed-broadcast, including FP8 KV-cache scales for backend combinations that support
them, identical to the conventional collective transport.
2. **`init_nccl_reshard_comm_group()`** — creates the bulk-path communicator(s): **one
NCCL group per training PP stage**, each spanning that stage's training ranks plus
*all* generation ranks (non-PP is simply `pp_size == 1`, a single group over
Expand Down Expand Up @@ -135,10 +145,11 @@ realized **locally**:
(sent as-is); grouped MoE experts get a `pre` hook that stacks this rank's per-expert
views into a `[num_local_experts, ...]` tensor fresh at each refit.
* On the **generation side**, a direct parameter's `base` is the live vLLM parameter
(received into in place); a parameter that is a slice of a fused vLLM tensor (dense
`gate_up_proj`, grouped-expert `w13`/`w2`) gets a `pre` hook that allocates a receive
buffer for its region and a `post` hook that copies the received shard back into the
fused parameter.
(received into in place). Conventional fused parameters use `pre`/`post` hooks to
receive a component and copy it into the appropriate local region. BF16
FlashInfer TRTLLM grouped experts instead receive into canonical EP-local staging
tensors; `post` loads each logical expert with its global expert ID through vLLM's
native weight loader.

### Execution Flow: Refit Time

Expand All @@ -159,7 +170,9 @@ Every training step (with in-flight weight updates, concurrently with generation
are distributed across `NRL_REFIT_NUM_STREAMS` CUDA streams so different stages'
reshards overlap. For each parameter it runs `pre` (receive-buffer allocation), calls
`xferdtensor(None, ..., dst, ..., group, stream)`, then `post` (copy back into the
fused parameter).
fused parameter or load staged TRTLLM experts). After every transfer completes, the
TRTLLM path finalizes vLLM's native layerwise reload once to restore the packed runtime
layout.

### The Misc Path

Expand Down Expand Up @@ -198,10 +211,11 @@ generation side maps those HF names onto whatever its own storage layout is.
`nccl_reshard_refit()` send loop; the misc packed-broadcast producer.
* **Generation side** (`vllm_backend.py`): building `hf_to_local_param_map` — mapping HF
names onto vLLM's fused parameters (`qkv_proj`, `gate_up_proj`, grouped-expert
`w13_weight`/`w2_weight`) with `pre`/`post` hooks for the slice regions, which is
deliberately **shape-driven** so the same code handles generation TP and generation
EP; the comm bootstrap methods; the `nccl_reshard_refit()` receive loop; the misc
consumer feeding `load_weights`.
`w13_weight`/`w2_weight`) with `pre`/`post` hooks for slice regions or canonical
TRTLLM staging, which is deliberately **shape-driven** so the same code handles
supported generation parallelism; the comm bootstrap methods; the
`nccl_reshard_refit()` receive loop; the misc consumer feeding `load_weights`; and
backend-specific finalization after all weights arrive.

**To extend to a new backend**, the only piece with genuinely new logic is
`build_hf_to_local_param_map`. Everything else is boilerplate that follows a fixed
Expand All @@ -210,9 +224,10 @@ contract and can be copied from the existing backend almost verbatim.
**The one backend-specific implementation — `build_hf_to_local_param_map`:** resolve
each bulk HF name to your local storage as a `LocalParamSpec` — `base` for tensors
sent/received as-is, and `pre`/`post` hooks wherever your layout requires staging
(fused/merged tensors, layout conversions, grouped-expert stacking). This is the *only*
place your backend's parameter layout is encoded; all cross-mesh byte movement is
already handled by the shared metadata and `xferdtensor`.
(fused/merged tensors, layout conversions, grouped-expert stacking). Backends that
rebuild runtime storage may also need one transport-level finalizer after all specs have
run. These are the only places the backend's parameter layout is encoded; all cross-mesh
byte movement is already handled by the shared metadata and `xferdtensor`.

(A new *training* backend additionally has to produce the HF-named metadata — names,
global shapes, dtypes, and the parallelism description the agnostic builder consumes —
Expand Down
37 changes: 37 additions & 0 deletions docs/fp8.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,43 @@ attention, the router, and the language-model head in BF16:
- model.layers.*.mlp.gate
```

`num_first_layers_in_bf16` and `num_last_layers_in_bf16` keep complete
transformer layers in BF16. NeMo RL reads the model configuration and parameter
names, so these options do not require a model-specific `model.layers` or
`backbone.layers` prefix. The patterns above still apply to every middle layer.

For example, this Nemotron 3.5 Lightning scope keeps the first two and last six
layers in BF16. In the middle layers it quantizes only the non-shared routed
experts. Attention, Mamba projections, routers, shared experts, latent
projections, and MTP remain in BF16:

```yaml
policy:
generation:
vllm_cfg:
precision: fp8
is_mx: true
num_first_layers_in_bf16: 2
num_last_layers_in_bf16: 6
quantization_ignore_patterns:
- "*layers.*.mixer.qkv_proj"
- "*layers.*.mixer.o_proj"
- "*layers.*.mixer.in_proj"
- "*layers.*.mixer.out_proj"
- "*layers.*.mixer.up_proj"
- "*layers.*.mixer.down_proj"
- "*layers.*.mixer.gate"
- "*layers.*.mixer.shared_experts.*"
- "*layers.*.mixer.fc1_latent_proj"
- "*layers.*.mixer.fc2_latent_proj"
- "*mtp.*"
```

To quantize QKVO as well as the routed experts, remove the `qkv_proj` and
`o_proj` entries. The first two and last six layers still remain entirely in
BF16. Check the logged effective ignore list when adding a new model family;
an ignore pattern that matches no module is usually a naming error.

`lm_head` is always excluded from FP8 and MXFP8 quantization, even when it is
not listed in `quantization_ignore_patterns` in the YAML configuration.
Models with MTP layers must list their MTP module names explicitly, for example
Expand Down
1 change: 1 addition & 0 deletions docs/guides/models/qwen/qwen3-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ authoritative settings.
| Qwen3.5-9B-Base | LLM | GRPO | Megatron | 1n8g | [`grpo-qwen3.5-9b-1n8g-megatron-fp8.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-9b-1n8g-megatron-fp8.yaml) |
| Qwen3.5-35B-A3B-Base | LLM | GRPO | Megatron | 2n8g | [`grpo-qwen3.5-35ba3b-2n8g-megatron-ep16tp2cp2.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-35ba3b-2n8g-megatron-ep16tp2cp2.yaml) |
| Qwen3.5-35B-A3B-Base | LLM | GRPO | Megatron | 2n8g | [`grpo-qwen3.5-35ba3b-2n8g-megatron-ep16tp2-fp8.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-35ba3b-2n8g-megatron-ep16tp2-fp8.yaml) |
| Qwen3.5-35B-A3B-Base | LLM | GRPO | Megatron | 6n4g | [`grpo-qwen3.5-35ba3b-6n4g-async-1off-bf16-trtllm.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-35ba3b-6n4g-async-1off-bf16-trtllm.yaml) |
| Qwen3.5-35B-A3B-Base | LLM | GRPO | AutoModel | 2n8g | [`grpo-qwen3.5-35ba3b-2n8g-automodel-ep16.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-35ba3b-2n8g-automodel-ep16.yaml) |
| Qwen3.5-35B-A3B-Base | LLM | GRPO | AutoModel | 4n8g | [`grpo-qwen3.5-35ba3b-dapo-4n8g-automodel.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-35ba3b-dapo-4n8g-automodel.yaml) |
| Qwen3.5-397B-A17B | LLM | GRPO | Megatron | 32n8g | [`grpo-qwen3.5-397ba17b-32n8g-megatron.v2.yaml`](../../../../examples/configs/recipes/llm/grpo-qwen3.5-397ba17b-32n8g-megatron.v2.yaml) |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defaults: grpo-qwen3.5-35ba3b-2n8g-megatron-ep16tp2cp2.yaml
loss_fn:
use_importance_sampling_correction: true
truncated_importance_sampling_type: tis
truncated_importance_sampling_ratio: 2
grpo:
async_grpo:
enabled: true
in_flight_weight_updates: true
checkpointing:
checkpoint_dir: results/grpo-qwen3.5-35ba3b-6n4g-async-1off-bf16-trtllm
policy:
generation:
refit_transport: nccl_reshard
colocated:
enabled: false
resources:
gpus_per_node: 4
num_nodes: 2
vllm_cfg:
async_engine: true
precision: bfloat16
expert_parallel_size: 4
gpu_memory_utilization: 0.8
enforce_eager: false
vllm_kwargs:
moe_backend: flashinfer_trtllm
expert_placement_strategy: linear
logger:
wandb:
name: grpo-qwen3.5-35ba3b-6n4g-async-1off-bf16-trtllm
cluster:
gpus_per_node: 4
num_nodes: 6
segment_size: 2
51 changes: 36 additions & 15 deletions nemo_rl/models/generation/vllm/quantization/fp8.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import os
import warnings
from collections.abc import Iterable, Iterator, Sequence
from collections.abc import Callable, Iterable, Iterator, Sequence
from dataclasses import dataclass, field
from typing import Any
from unittest.mock import patch
Expand Down Expand Up @@ -264,9 +264,30 @@ def init_fp8(vllm_cfg, model_name, model_parallel_size):
quantization_ignore_patterns = [
pattern.strip() for pattern in quantization_ignore_patterns
]

num_first_layers_in_bf16 = vllm_cfg.get("num_first_layers_in_bf16", 0)
num_last_layers_in_bf16 = vllm_cfg.get("num_last_layers_in_bf16", 0)
get_text_config = getattr(config, "get_text_config", None)
text_config = (
get_text_config()
if callable(get_text_config)
else getattr(config, "text_config", config)
)
num_hidden_layers = text_config.num_hidden_layers
for field_name, value in (
("num_first_layers_in_bf16", num_first_layers_in_bf16),
("num_last_layers_in_bf16", num_last_layers_in_bf16),
):
if not isinstance(value, int) or isinstance(value, bool):
raise ValueError(f"{field_name} must be an integer")
if not 0 <= value <= num_hidden_layers:
raise ValueError(
f"{field_name} must be between 0 and {num_hidden_layers}, got {value}"
)

fp8_config_kwargs = {
"num_first_layers_in_bf16": vllm_cfg.get("num_first_layers_in_bf16", 0),
"num_last_layers_in_bf16": vllm_cfg.get("num_last_layers_in_bf16", 0),
"num_first_layers_in_bf16": num_first_layers_in_bf16,
"num_last_layers_in_bf16": num_last_layers_in_bf16,
"model_parallel_size": model_parallel_size,
"kv_cache_dtype": kv_cache_dtype,
"use_fp8_weights": use_fp8_weights,
Expand Down Expand Up @@ -301,15 +322,13 @@ def init_fp8(vllm_cfg, model_name, model_parallel_size):
monkey_patch_vllm_ray_executor(global_fp8_config)

# create fp8 kwargs for vllm's LLM(...)
num_first_layers_in_bf16 = vllm_cfg.get("num_first_layers_in_bf16", 0)
num_last_layers_in_bf16 = vllm_cfg.get("num_last_layers_in_bf16", 0)
if global_fp8_config.is_mx:
fp8_block_quant_kwargs = dict(MXFP8_BLOCK_QUANT_KWARGS)
else:
fp8_block_quant_kwargs = dict(FP8_BLOCK_QUANT_KWARGS)
if num_first_layers_in_bf16 > 0 or num_last_layers_in_bf16 > 0:
with init_empty_weights():
model = AutoModel.from_config(config)
model = AutoModel.from_config(config, trust_remote_code=True)
param_names = [name for name, _ in model.named_parameters()]

bf16_params = []
Expand All @@ -321,8 +340,8 @@ def init_fp8(vllm_cfg, model_name, model_parallel_size):
layers = [
l
for l in range(
config.num_hidden_layers - num_last_layers_in_bf16,
config.num_hidden_layers,
num_hidden_layers - num_last_layers_in_bf16,
num_hidden_layers,
)
]
bf16_params.extend(_get_params_in_layers(param_names, layers))
Expand All @@ -338,7 +357,7 @@ def init_fp8(vllm_cfg, model_name, model_parallel_size):
)
if quantization_ignored_layer_kws:
with init_empty_weights():
model = AutoModel.from_config(config)
model = AutoModel.from_config(config, trust_remote_code=True)
param_names = [
f"model.{name}".removesuffix(".weight").replace(
"model.backbone.", "backbone."
Expand Down Expand Up @@ -607,15 +626,17 @@ def get_quantized_weight_iterator(


def load_weights(
weights: Iterable[tuple[str, torch.Tensor]], model_runner: Any
weights: Iterable[tuple[str, torch.Tensor]],
model_runner: Any,
*,
model_load_weights: Callable[..., object] | None = None,
) -> None:
"""Quantize weights for the legacy direct model-loading path."""
# Finally load the weights into vllm
model_runner.model.load_weights(
if model_load_weights is None:
model_load_weights = model_runner.model.load_weights
model_load_weights(
get_quantized_weight_iterator(
weights,
model_runner,
refit_with_reload_api=False,
weights, model_runner, refit_with_reload_api=False
)
)

Expand Down
Loading
Loading