Skip to content

Add native FP8 expert support to REAP - #3003

Open
ieBoytsov wants to merge 1 commit into
vllm-project:mainfrom
ieBoytsov:reap-native-fp8
Open

Add native FP8 expert support to REAP#3003
ieBoytsov wants to merge 1 commit into
vllm-project:mainfrom
ieBoytsov:reap-native-fp8

Conversation

@ieBoytsov

Copy link
Copy Markdown

Summary:

Currently REAP can't work with fp8 checkpoints because LinearExperts2D assumes a checkpoint packs experts as a list of nn.linear instances which is true for a lot of models but experts in FP8 checkpoints (at least some of what I saw) are packed all together into a fused container FP8Experts so LinearExperts2D can't iterate them. This PR fixes the problem.

The only way to use fp8 checkpoints with REAP now is to dequantize chpt in the beginning and run calibration with bf/fp16 weights. This also saved pruned model in bf/fp16 rather than in original fp8 which is ambigious.

Adds REAP support for packed native FP8 MoE experts, including activation-norm collection and structural pruning while preserving FP8 weights and scales. Updates router and correction-bias pruning and adds coverage for native FP8 expert detection, calibration, and pruning.

Test plan

Validated with minimax-m2.5 model and 38 REAP tests plus Ruff checks

Signed-off-by: Ilya Boytsov <ieboytsov@nebius.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d47d2f3-cd85-4ab0-884d-858fb96df253

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@mergify mergify Bot added the two-reviews When a PR requires two reviews label Aug 6, 2026
@mergify

mergify Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 2 of 2 protections blocking · waiting on 👀 reviews

Protection Waiting on
🔴 Require one maintainer review 👀 reviews
🔴 Require two reviews 👀 reviews

🔴 Require one maintainer review

Waiting for any of

  • approved-reviews-by=HDCharles
  • approved-reviews-by=brian-dellabetta
  • approved-reviews-by=dsikka
  • approved-reviews-by=kylesayrs
  • approved-reviews-by=yiliu30
This rule is failing.

All PRs must have at least one approving review from a maintainer before merging.

  • any of:
    • approved-reviews-by=HDCharles
    • approved-reviews-by=brian-dellabetta
    • approved-reviews-by=dsikka
    • approved-reviews-by=kylesayrs
    • approved-reviews-by=yiliu30
  • #changes-requested-reviews-by = 0

🔴 Require two reviews

Waiting for

  • #approved-reviews-by >= 2
This rule is failing.

PRs labelled "two-reviews" must have at least two approving reviews before merging.

  • #approved-reviews-by >= 2
  • #changes-requested-reviews-by = 0

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces REAP (Representation-based Expert Pruning) support for native fine-grained FP8 experts in Transformers. It adds the FP8PrunableExperts class, defines the ReapPrunableExpertsProtocol interface, and updates the REAPPruningModifier and utility functions to handle both standard 2D linear experts and packed FP8 expert containers. Comprehensive unit tests are also added to verify the new pruning lifecycle. The review feedback highlights three key areas for improvement: wrapping the FP8Experts import in a try-except block to maintain backward compatibility with older transformers versions, adding defensive checks in _prune_expert_tensor to handle None values safely, and converting the expert_indices tensor to a Python list to prevent host-device synchronization bottlenecks during iteration.

import torch
import torch.nn as nn
from compressed_tensors import align_module_device
from transformers.integrations.finegrained_fp8 import FP8Experts

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.

high

Unconditionally importing FP8Experts from transformers.integrations.finegrained_fp8 will cause a ModuleNotFoundError or ImportError on environments running older versions of transformers that do not support fine-grained FP8. Since this module is imported unconditionally in utils.py, it breaks backward compatibility for all users of the library. Wrapping this import in a try-except block and defining a fallback dummy class with a dummy forward method ensures backward compatibility.

Suggested change
from transformers.integrations.finegrained_fp8 import FP8Experts
try:
from transformers.integrations.finegrained_fp8 import FP8Experts
except ImportError:
class FP8Experts:
def forward(self, *args, **kwargs):
pass

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

fair

Comment on lines +433 to +438
retained_t = torch.tensor(retained, dtype=torch.long)
with align_module_device(holder):
value = getattr(holder, name)
retained_t = retained_t.to(value.device)
pruned = value.detach()[retained_t].contiguous()
requires_grad = value.requires_grad

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.

high

In _prune_expert_tensor, if a parameter or buffer exists but its value is None (which is common for optional parameters/buffers like bias or e_score_correction_bias in some configurations), getattr(holder, name) will return None. Attempting to access value.device or value.requires_grad will then raise an AttributeError. Adding a defensive check to return early if value is None prevents this potential runtime crash.

    value = getattr(holder, name, None)
    if value is None:
        return

    retained_t = torch.tensor(retained, dtype=torch.long)
    with align_module_device(holder):
        retained_t = retained_t.to(value.device)
        pruned = value.detach()[retained_t].contiguous()
        requires_grad = getattr(value, "requires_grad", False)

Comment on lines +66 to +73
if calibrate_all:
expert_indices = range(self.num_experts)
else:
expert_indices = (
torch.greater(expert_mask.sum(dim=(-1, -2)), 0)
.nonzero(as_tuple=False)
.view(-1)
)

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.

medium

Iterating directly over expert_indices when it is a PyTorch GPU tensor (returned by .nonzero().view(-1)) causes host-device synchronization on every single iteration of the loop. This introduces a significant performance bottleneck during calibration/inference. Converting the tensor to a standard Python list of integers using .tolist() before iterating avoids these synchronizations and dramatically improves execution speed.

Suggested change
if calibrate_all:
expert_indices = range(self.num_experts)
else:
expert_indices = (
torch.greater(expert_mask.sum(dim=(-1, -2)), 0)
.nonzero(as_tuple=False)
.view(-1)
)
if calibrate_all:
expert_indices = list(range(self.num_experts))
else:
expert_indices = (
torch.greater(expert_mask.sum(dim=(-1, -2)), 0)
.nonzero(as_tuple=False)
.view(-1)
.tolist()
)

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to llm-compressor. Please add the ready label when the PR is ready for review.

Note: This is required to complete the testing suite, please only add the label once the PR is code complete and local testing has been performed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

two-reviews When a PR requires two reviews

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant