Skip to content

[Pytorch][Common] Hybrid quantization - #2817

Merged
ptrendx merged 84 commits into
NVIDIA:mainfrom
negvet:hybrid_quantization
Aug 4, 2026
Merged

[Pytorch][Common] Hybrid quantization#2817
ptrendx merged 84 commits into
NVIDIA:mainfrom
negvet:hybrid_quantization

Conversation

@negvet

@negvet negvet commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator

Description

Hybrid (per-direction) quantization. Hybrid means rowwise/colwise can use different formats via CustomRecipe(qfactory).
This is an experimental feature.
The main problem that it tries to solve is that precision requirements are non-uniform.

Current recipes set one format for both rowwise and colwise directions.
Hybrid quantization enables, e.g. MXFP8 fwd and NVFP4 bwd (or vice versa) or any other valid combination. No need for a hardcoded recipe for every combination.

Composer-style (Composer 2 paper) grouped GEMM recipe, e.g. row-scaled NVFP4 fwd + MXFP8 bwd:

# CustomRecipe calls quantization_factory(role) for each quantized tensor
# Factory chooses formats

def hybrid_factory(role):
    is_grouped_linear = role is not None and role.module_type == "grouped_linear"
    is_linear = role is not None and role.module_type == "linear"

    if is_grouped_linear and role.tensor_type == "input":
        return HybridQuantizer(
            rowwise_quantizer=NVFP4Quantizer(row_scaled_nvfp4=True, ...),
            columnwise_quantizer=MXFP8Quantizer(...),
        )

    if is_grouped_linear and role.tensor_type == "weight":
        return HybridQuantizer(
            rowwise_quantizer=NVFP4Quantizer(...),
            columnwise_quantizer=MXFP8Quantizer(...),
        )

    if is_grouped_linear and role.tensor_type == "grad_output":
        return MXFP8Quantizer(...)

    if is_linear:
        return MXFP8Quantizer(...)

    return MXFP8Quantizer(...)

recipe = CustomRecipe(qfactory=hybrid_factory)
with autocast(recipe=recipe):
    y = model(x)

By default, the above factory uses columnwise_source="original", so MXFP8 backward operands are quantized from the original high-precision tensor. Use columnwise_source="rowwise_dequantized" when the backward operand should be derived from the dequantized rowwise NVFP4 forward value.

C++ optimizations (fusions, etc.) will come as standalone PRs. cc @kainzhong

TODO:

  • Convergence of base (non-hybrid) recipes
  • HybridFloat8BlockScaling is xfailed under FSDP2 because dim-0 shards can split 128-row block-scale tiles, producing all-gathered scale buffers whose shape does not match the global tensor.
  • Delayed scaling
  • Mid-training recipe change

Follow-up issue tracker #3158.

Integration

Ecosystem integration (all functional, unit-tested):

  • [Done] quantized_model_init
  • [Done] FSDP2 (TODO: optimize communication buffers)
  • [Done] CPU offloading
  • [Done] Activation recomputation
  • [Done] TP/SP (TODO: enable quantized AG)

Megatron-LM integration status:

  • [Done] 1 GPU baseline
  • [Done] DP + distributed optimizer
  • [TODO] quantized_model_init + --fp{4,8}-param-gather + dist opt (persistent low-precision params via quantized_model_init + sharded-master FP32 → quantized cast via quantize_master_weights.)
    - [Done] Per-tensor Float8 hybrid (delayed and/or current, any per-direction combination
    including same-format, cross-format Float8, single-direction)
    - [TODO] Per-block hybrid sub-quantizers (MXFP8, NVFP4, Float8Blockwise) — each rejected per-direction by quantize_master_weights; unblocker is TE-side cast-helper / kernel.
  • [TODO] Megatron-FSDP + --fp{4,8}-param-gather (fix private attribute access)
  • [TODO] Torch FSDP2 + --fp{4,8}-param-gather
    - [Done] TE-side hybrid FSDP2 path works end-to-end for Float8 / MXFP8 / Float8Blockwise sub-storages (TODO: need some minor MLM update)
    - [TODO] NVFP4 sub-storage FSDP2 hooks
  • [Done] Activation recompute
  • [Done] CPU offload
  • [Done] TP/SP/PP
  • [Done] MoE + EP + grouped GEMM (qwen3 MoE; _hybrid_split_quantize under Megatron MoE)

Review

Total diff +14000
New hybrid source (hybrid_tensor.py, hybrid_tensor_storage.py, identity_tensor.py, identity_tensor_storage.py) ~1800
Adjacent modifications ~1500
Tests are the rest (~10K)

Suggested reading order

  1. Foundation — 7553e6a: Python containers + quantize/gemm dispatch/unwrap
  • tensor/hybrid_tensor.py — HybridQuantizer + HybridQuantizedTensor
    -columnwise_source controls whether columnwise quantization uses the original input or the rowwise-dequantized value.
  • tensor/storage/hybrid_tensor_storage.py
  • cpp_extensions/gemm.py — _unwrap_hybrid_A/B
  • common/transpose/quantize_transpose_square_blockwise.cu - Block FP8 columnwise-only null-checks
  • Module hooks in module/{base,grouped_linear,layernorm_linear,layernorm_mlp}.py
  • Tests: TestHybridQuantizer*, TestHybridGemmBitwiseIdentical* (proves zero-overhead vs vanilla recipes when both formats match), TestHybridDirectionUnwrap*, TestHybridGroupedLinear*

1.1 Identity passthrough — b99277a

  • tensor/identity_tensor.py and tensor/storage/identity_tensor_storage.py — IdentityQuantizer / IdentityTensor high-precision passthrough
  • custom_recipes/quantization_factory_zoo.py — examples for high-precision fwd/bwd directions and columnwise_source="rowwise_dequantized"
  • Tests: test_identity_quantizer.py plus hybrid tests covering Identity inside HybridQuantizer
  1. quantized_model_init + FusedAdam — f80f5d0
  • hybrid_tensor.py::HybridQuantizer.update_quantized — delegates to each sub-quantizer; unblocks workspace-cache quantize_() and FusedAdam writeback
  • module/base.py workspace-cache invalidation
  • Tests: TestHybridQuantizedModelInit, TestHybridFusedAdam, TestHybridQuantizedParamsEndToEnd, TestHybridCheckpoint, TestQuantizedParamsEquivalence*
  1. FSDP2 support — 2185b30
  • New base FSDP2 buffer protocol on QuantizedTensorStorage: fsdp_buffer_fields / fsdp_extract_buffers / fsdp_assign_gathered. Generic, reusable beyond hybrid.
  • Per-format overrides on Float8TensorStorage (direction-aware) and MXFP8TensorStorage (trips/re-applies scale alignment padding around the gather)
  • hybrid_tensor.py::fsdp_pre/post_all_gather + torch_dispatch for the FSDP2 op set (view, split, as_strided, slice, copy_, new_zeros, clone, detach)
  • Non-safety in float8_tensor.py and mxfp8_tensor.py for single-direction sub-storages (columnwise-only on Hopper/L40)
  • Tests: TestHybridTorchDispatchFSDP2Ops, TestHybridFsdpPreAllGatherProtocol, TestHybridFsdpRoundtrip (bitwise-exact against manual all_gather(dequantize(shard))), plus tests/pytorch/distributed/fsdp2_tests/
  1. CPU offloading — 103fffe
  • hybrid_tensor_storage.py::clear() (v1 path) + prepare_for_saving / restore_from_saved chain (v2 path)
  • hybrid_tensor.py::detach() re-wraps each sub-storage via make_like (required by cpu_offload_v2's detach → prepare_for_saving pattern; sharing sub-storage objects would null-out fields on the original)
  • TestHybridCpuOffloadPushPop, plus updates to test_cpu_offloading*.py
  1. Activation recomputation — 16fb371
  • Uses existing QuantizedTensorStorage::prepare_for_saving / restore_from_saved protocol, preserving ordering across both sub-storages
  • Tests: 20 bitwise tests in TestHybridActivationRecompute
  1. TP/SP — a50fd63
  • hybrid_tensor.py::HybridQuantizer.supports_only_rowwise_all_gather — overrides to handle the NVFP4 columnwise-dequantize gap in the BF16 fallback path
  • distributed.py::gather_along_first_dim — hybrid branch re-quantizes with both directions after AG (since hybrid has no _create_transpose synthesis path)
  • Tests: 9 distributed tests in run_hybrid_tp_sp.py / test_hybrid_tp_sp.py
  1. Megatron-LM integration — a164cd3
  • tensor/utils.py::_route_hybrid_to_buckets — per-direction dispatch for quantize_master_weights: iterates both sub-storages, routes each independently into the per-format bucket matching its own sub-quantizer type
  • Hybrid branches in replace_raw_data and post_all_gather_processing
  • Today: per-tensor Float8 sub-quantizers (delayed + current) work in any per-direction combination. Per-block sub-quantizers raise per-direction with in-code TODOs naming the unblocker.
  • Tests: TestHybridQuantizeMasterWeights, TestHybridPostAllGatherProcessing

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

Please list the changes introduced in this PR:

  • Change A
  • Change B

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@greptile-apps

greptile-apps Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces hybrid (per-direction) quantization for TransformerEngine, allowing rowwise and columnwise representations to use different quantization formats (e.g. MXFP8 forward + NVFP4 backward). It adds HybridQuantizer/HybridQuantizedTensor and an IdentityQuantizer/IdentityTensor passthrough as foundational building blocks, then wires them through GEMM dispatch, FSDP2, CPU offloading, activation recomputation, and TP/SP.

  • New tensor infrastructure (hybrid_tensor.py, hybrid_tensor_storage.py, identity_tensor.py, identity_tensor_storage.py): ~1 800 lines implementing the compositing quantizer, FSDP2 all-gather protocol (buffer-field protocol + fsdp_pre/post_all_gather), prepare_for_saving/restore_from_saved, and full __torch_dispatch__ coverage for FSDP2 ops.
  • GroupedLinear hybrid split-quantize (_split_quantize_hybrid in grouped_linear.py): correctly handles columnwise_source=\"rowwise_dequantized\" by dequantizing the grouped rowwise results before re-splitting for columnwise quantization, and validates quantizer-list homogeneity before dispatch.
  • Megatron-LM distopt integration (tensor/utils.py): _route_hybrid_to_buckets decomposes a HybridQuantizedTensor into per-direction entries and routes each into the per-format cast bucket; Hopper columnwise-only sub-storages are rejected before mutation by _validate_per_tensor_fp8_fsdp_hopper_policy (covering both delayed and current scaling).

Confidence Score: 4/5

Safe to merge for the experimental hybrid quantization feature; the major correctness bugs from previous review rounds are confirmed fixed, and the remaining known gaps are well-documented TODOs (NVFP4 FSDP2, per-block distopt).

All P1 findings from previous review iterations — MX scale truncation floor-vs-ceil, columnwise_source='rowwise_dequantized' ignored in grouped path, make_empty internal flag leak, fsdp_buffer_fields not direction-aware on Hopper, update_usage missing after post_all_gather, None entry crash in _hybrid_split_quantize — are confirmed fixed. The Hopper columnwise-only distopt guard now covers both Float8Quantizer and Float8CurrentScalingQuantizer. The only new finding is a P2 CPU–GPU sync in IdentityQuantizer.update_quantized when noop_flag is active and buffer metadata changes, a rare code path. Known limitations (NVFP4 FSDP2 sub-storage, per-block hybrid distopt, delayed-scaling requests inside HybridQuantizer) are clearly documented as in-code TODOs with tracking issues.

Files Needing Attention: tensor/utils.py (_route_hybrid_to_buckets and _validate_per_tensor_fp8_fsdp_hopper_policy) and module/grouped_linear.py (_split_quantize_hybrid) are the most operationally critical paths and would benefit from careful integration testing on Hopper/L40 hardware before wide adoption.

Important Files Changed

Filename Overview
transformer_engine/pytorch/tensor/hybrid_tensor.py Core new file: HybridQuantizer and HybridQuantizedTensor. Full FSDP2 dispatch (pre/post all-gather, view/split/as_strided/copy_/new_zeros/clone), columnwise_source handling, detach/contiguous/pickle. Previous thread issues (internal flag leak, fsdp_post_all_gather missing update_usage) confirmed fixed.
transformer_engine/pytorch/tensor/storage/hybrid_tensor_storage.py HybridQuantizedTensorStorage: composites rowwise/columnwise sub-storages with delegation for dequantize, size, device, prepare_for_saving, restore_from_saved, and view. Repr fixed (no NoneType). Clean.
transformer_engine/pytorch/tensor/identity_tensor.py New IdentityQuantizer/IdentityTensor passthrough: holds HP data directly, supports FSDP2 pre/post all-gather, torch_dispatch for view/split/copy_/new_zeros/clone. noop_flag path in update_quantized can cause a CPU-GPU sync on shape/dtype mismatch (rare edge case).
transformer_engine/pytorch/tensor/storage/identity_tensor_storage.py IdentityTensorStorage: HP passthrough storage, implements fsdp_buffer_fields returning ('_hp_data',), prepare_for_saving, restore_from_saved. Direction-agnostic. Clean.
transformer_engine/pytorch/module/grouped_linear.py _split_quantize_hybrid correctly handles columnwise_source='rowwise_dequantized' by dequantizing row results before re-splitting; _validate_grouped_quantizer_list enforces homogeneity. Previous thread issues (AttributeError on mixed lists, None entry handling) confirmed fixed.
transformer_engine/pytorch/cpp_extensions/gemm.py _unwrap_tensor now raises RuntimeError on None (previous silent None return fixed); hybrid sub-storage unwrapping routes correctly by direction. _validate_native_gemm_output_quantizer guards custom output quantizers.
transformer_engine/pytorch/tensor/utils.py _route_hybrid_to_buckets and _validate_per_tensor_fp8_fsdp_hopper_policy cover both Float8Quantizer and Float8CurrentScalingQuantizer for Hopper FSDP guard. _update_transpose_only_float8_flat_fragment handles non-FSDP Hopper columnwise-only path for both delayed and current scaling.
transformer_engine/pytorch/tensor/storage/float8_tensor_storage.py fsdp_buffer_fields is now direction-aware: returns ('_transpose',) when _data is None on Hopper columnwise-only sub-storages. fsdp_assign_gathered correctly resets _transpose_invalid after column-major gather.
transformer_engine/pytorch/tensor/storage/mxfp8_tensor_storage.py MXFP8 fsdp_extract_buffers scale truncation uses ceil division (previous floor-division bug fixed in c7e11d2). fsdp_assign_gathered restores padding correctly.
transformer_engine/pytorch/tensor/storage/float8_blockwise_tensor_storage.py fsdp_extract_buffers handles rowwise-only or columnwise-only correctly for hybrid sub-storage use (each sub-storage is direction-pinned by HybridQuantizer). Bidirectional case would misalign field_names vs buffers, but unreachable through hybrid context.
transformer_engine/pytorch/tensor/float8_tensor.py clone() now handles _data=None (Hopper columnwise-only sub-storage). Float8CurrentScalingQuantizer.is_requantization_safe() added. _columnwise_shape_for helper added for shape inference.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class Quantizer {
        +rowwise_usage: bool
        +columnwise_usage: bool
        +quantize(tensor) QuantizedTensorStorage
        +make_empty(shape) QuantizedTensorStorage
        +update_quantized(src, dst) QuantizedTensorStorage
    }
    class HybridQuantizer {
        +rowwise_quantizer: Quantizer
        +columnwise_quantizer: Quantizer
        +columnwise_source: str
        +quantize_impl(tensor) HybridQuantizedTensor
        +update_quantized(src, dst)
        +supports_only_rowwise_all_gather() bool
        +is_requantization_safe() bool
    }
    class IdentityQuantizer {
        +dtype: Optional[torch.dtype]
        +quantize_impl(tensor) IdentityTensor
        +update_quantized(src, dst)
        +is_requantization_safe() bool
    }
    class QuantizedTensorStorage {
        +fsdp_buffer_fields() Tuple
        +fsdp_extract_buffers()
        +fsdp_assign_gathered(gathered, meta)
        +prepare_for_saving()
        +restore_from_saved(tensors)
    }
    class HybridQuantizedTensorStorage {
        +_rowwise_storage: Optional[QuantizedTensorStorage]
        +_columnwise_storage: Optional[QuantizedTensorStorage]
        +_quantizer: HybridQuantizer
        +dequantize(dtype) Tensor
        +update_usage(rowwise, columnwise)
        +clear()
    }
    class HybridQuantizedTensor {
        +fsdp_pre_all_gather(mesh)
        +fsdp_post_all_gather(outputs, meta)
        +__torch_dispatch__(func)
        +detach() HybridQuantizedTensor
    }
    class IdentityTensorStorage {
        +_hp_data: Optional[Tensor]
        +fsdp_buffer_fields()
        +dequantize(dtype) Tensor
    }
    class IdentityTensor {
        +fsdp_pre_all_gather(mesh)
        +fsdp_post_all_gather(outputs, meta)
        +__torch_dispatch__(func)
    }
    Quantizer <|-- HybridQuantizer
    Quantizer <|-- IdentityQuantizer
    QuantizedTensorStorage <|-- HybridQuantizedTensorStorage
    HybridQuantizedTensorStorage <|-- HybridQuantizedTensor
    QuantizedTensorStorage <|-- IdentityTensorStorage
    IdentityTensorStorage <|-- IdentityTensor
    HybridQuantizer --> Quantizer : rowwise_quantizer
    HybridQuantizer --> Quantizer : columnwise_quantizer
    HybridQuantizedTensorStorage --> QuantizedTensorStorage : _rowwise_storage
    HybridQuantizedTensorStorage --> QuantizedTensorStorage : _columnwise_storage
Loading

Reviews (37): Last reviewed commit: "Fix CI" | Re-trigger Greptile

Comment thread transformer_engine/pytorch/module/grouped_linear.py Outdated
Comment thread transformer_engine/pytorch/tensor/storage/hybrid_tensor_storage.py
Comment thread transformer_engine/pytorch/tensor/hybrid_tensor.py Outdated

@timmoon10 timmoon10 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall I think this moves us in a good direction. I see some minor bugs, as well as bugs reported by @greptile-apps.

Comment on lines +52 to +53
rowwise_result = self.rowwise_quantizer.quantize(tensor)
columnwise_result = self.columnwise_quantizer.quantize(tensor)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we handle the case where not all usages are needed? I'd expect something like:

Suggested change
rowwise_result = self.rowwise_quantizer.quantize(tensor)
columnwise_result = self.columnwise_quantizer.quantize(tensor)
rowwise_result = self.rowwise_quantizer.quantize(tensor) if self.rowwise_usage else None
columnwise_result = self.columnwise_quantizer.quantize(tensor) if self.columnwise_usage else None

@negvet negvet May 21, 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.

Fixed in 4858491

requires_grad: bool = False,
pin_memory: bool = False,
) -> HybridQuantizedTensor:
self.rowwise_quantizer.internal = True

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we just set internal=True in the constructor? I don't think we ever need PyTorch tensor functionality in the per-usage data.

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.

This would not work under FSDP2.

Comment thread transformer_engine/pytorch/tensor/hybrid_tensor.py Outdated
Comment on lines +1339 to +1355
def factory(role):
if role == "linear_weight":
return HybridQuantizer(
rowwise_quantizer=_make_fp8_quantizer(),
columnwise_quantizer=_make_mxfp8_quantizer(),
)
if role == "linear_input":
return HybridQuantizer(
rowwise_quantizer=_make_fp8_quantizer(),
columnwise_quantizer=_make_nvfp4_quantizer(),
)
if role in ("linear_grad_output", "linear_grad_input"):
return HybridQuantizer(
rowwise_quantizer=_make_mxfp8_quantizer(),
columnwise_quantizer=_make_nvfp4_quantizer(),
)
return None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is horrifying. Good test.

negvet and others added 10 commits April 6, 2026 10:26
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Comment thread transformer_engine/pytorch/module/grouped_linear.py Outdated
Comment thread transformer_engine/pytorch/tensor/hybrid_tensor.py
negvet and others added 2 commits April 29, 2026 16:02
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Comment thread transformer_engine/pytorch/tensor/storage/float8_tensor_storage.py
negvet added 3 commits May 13, 2026 12:34
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet
negvet requested a review from ksivaman as a code owner May 21, 2026 13:53
Comment thread transformer_engine/pytorch/tensor/float8_tensor.py
Comment on lines +27 to +30
# DCP serializes ``CustomRecipe`` via ``pickle``; closure-based qfactories
# (lambdas, inner functions referencing captured state) are not picklable,
# so the qfactory must live at module scope. See
# ``run_fsdp2_fused_adam.py::test_hybrid_dcp_output_parity``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This comment is potentially useful, but I don't think it is in the right place - shouldn't it be closer to the actual implementation?

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.

Fixed

Comment on lines +1177 to +1184
for param in model.parameters():
state = optimizer.state[param]
assert state["exp_avg"].dtype == torch.float32
assert state["exp_avg_sq"].dtype == torch.float32
if "master_param" in state:
assert state["master_param"].dtype == torch.float32

assert losses[-1] < losses[0], f"Loss did not decrease: {losses[0]:.4f} -> {losses[-1]:.4f}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's not a very strict test, is there a way for us to do some numerical correctness comparisons?

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.

Enabled check for the monotonic loss decrease (still mostly sanity), and also enabled hybrid vs vanilla bitwise recipe comparizon, see e.g. test_fused_adam_hybrid_vs_base_recipe_parity.

negvet and others added 3 commits July 22, 2026 12:32
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet

negvet commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

Comment thread transformer_engine/pytorch/module/linear.py Outdated
Comment thread transformer_engine/pytorch/distributed.py Outdated
Comment thread transformer_engine/pytorch/ops/basic/layer_norm.py Outdated
Comment thread transformer_engine/pytorch/quantized_tensor.py Outdated
Comment thread transformer_engine/pytorch/module/linear.py Outdated
Comment thread transformer_engine/pytorch/module/base.py Outdated
Comment thread transformer_engine/pytorch/cpp_extensions/gemm.py Outdated
Comment thread transformer_engine/pytorch/cpp_extensions/gemm.py Outdated
Comment thread transformer_engine/pytorch/module/grouped_linear.py Outdated
negvet and others added 3 commits July 24, 2026 13:59
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet

negvet commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

@negvet

negvet commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet

negvet commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

timmoon10
timmoon10 previously approved these changes Aug 3, 2026
Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet

negvet commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

pre-commit-ci Bot and others added 3 commits August 4, 2026 10:06
Signed-off-by: Evgeny <etsykunov@nvidia.com>
Signed-off-by: Evgeny <etsykunov@nvidia.com>
@negvet

negvet commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

/te-ci L0 L1

@ptrendx
ptrendx merged commit bce8162 into NVIDIA:main Aug 4, 2026
50 of 55 checks passed
pggPL added a commit to pggPL/TransformerEngine that referenced this pull request Aug 4, 2026
Brings main's 12 commits, including hybrid quantization (NVIDIA#2817), in through
the rebased base branch. Four conflicts:

- float8_tensor.py / storage/float8_tensor_storage.py: import lists, unioned
  (_resolve_view_shape from main, tensor_can_be_materialized from here).
- linear.py, tp_world_size block: kept this branch's backward_needs_input,
  which reads the args bundle.
- linear.py, `if fp8:` guard: both sides deleted a different statement from
  it -- this branch dropped assert_dim_for_fp8_exec (host-side shape check
  that does not trace), main dropped the save_original_input assert. Applying
  both deletions empties the block, so the `if fp8:` goes away. The
  save_original_input case is already handled earlier on this branch, which
  warns and disables it for delayed-scaling quantizers instead of asserting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Pawel Gadzinski <pgadzinski@nvidia.com>
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.

5 participants