Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fdaea9e
[PyTorch] Avoid concatenation copies for compiled split Linear parame…
pggPL Oct 5, 2026
289cff1
[PyTorch] Make deferred parameter concatenation explicit
pggPL Oct 5, 2026
43a33bb
[PyTorch] Simplify split Linear parameter handling
pggPL Oct 5, 2026
5d5c180
[PyTorch] Limit the split-parameter API refactor
pggPL Oct 5, 2026
bdb5bc1
Merge main into split_parameters_linear
pggPL Oct 12, 2026
73d58af
[PyTorch] Keep the frozen-weight bias fix out of split parameter support
pggPL Oct 12, 2026
122a2c9
[PyTorch] Read split parameter shape and gradient flags directly
pggPL Oct 14, 2026
156576e
[PyTorch] Pass split parameters as tensor lists
pggPL Oct 14, 2026
dd01b3a
[PyTorch] Use representation-neutral names for Linear operands
pggPL Oct 14, 2026
88b47c3
[PyTorch] Pass split Linear weights in separate tensor-list fields
pggPL Oct 16, 2026
bcf13f6
[PyTorch] Skip empty split-parameter bookkeeping in eager Linear
pggPL Oct 16, 2026
623baf8
[PyTorch] Make deferred Linear parameter lists optional
pggPL Oct 16, 2026
7b28093
[PyTorch] Trim split parameter tests
pggPL Oct 16, 2026
40974d3
[PyTorch] Materialize split Linear parameters inside eager forward
pggPL Oct 21, 2026
ddb3eaa
Merge upstream main into split_parameters_linear
pggPL Oct 27, 2026
f5a13d2
Merge upstream main and preserve split Linear documentation
pggPL Oct 27, 2026
acfce62
Merge upstream main into split_parameters_linear
pggPL Oct 28, 2026
303b093
[PyTorch] Materialize split LayerNormLinear parameters in eager forward
pggPL Oct 28, 2026
61e1854
[PyTorch] Consolidate split parameter integration tests
pggPL Oct 28, 2026
576b505
[PyTorch] Avoid repeated split-parameter validation
pggPL Oct 28, 2026
06415ad
Simplify deferred split parameter selection
pggPL Oct 28, 2026
d661987
Clarify split parameter preparation names
pggPL Oct 28, 2026
15b9973
Detect split backward inputs from saved metadata
pggPL Oct 28, 2026
63ccf35
Reuse adapter metadata to restore split parameters
pggPL Oct 28, 2026
4fa64a8
Cover split parameters in existing module tests
pggPL Oct 28, 2026
10105b3
Remove added split LayerNormLinear sanity scenarios
pggPL Oct 28, 2026
b04c1e3
Keep module output and gradient checks local to compile tests
pggPL Oct 28, 2026
4d29b8e
Use one execution path for compiled Linear tests
pggPL Oct 29, 2026
905f954
Preserve safe concatenation and no-bias LayerNormLinear behavior
pggPL Oct 29, 2026
bc6faaf
Test eager LayerNormLinear gradients with shared and separate split s…
pggPL Oct 29, 2026
79375c8
Merge main into split_parameters_linear
pggPL Nov 2, 2026
ecae1e5
Merge main into split_parameters_linear
pggPL Nov 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
86 changes: 71 additions & 15 deletions tests/pytorch/test_numerics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,9 @@ def test_mha_accuracy(dtype, bs, model, mask_type):
assert_allclose(te_output, torch_output, atol[dtype], rtol[dtype])


def _test_granular_accuracy(block, bs, dtype, config, delay_wgrad_compute=False, recipe=None):
def _test_granular_accuracy(
block, bs, dtype, config, delay_wgrad_compute=False, recipe=None, grad_output=None
):
reset_rng_states()
fp8 = recipe is not None
if fp8:
Expand All @@ -1493,8 +1495,11 @@ def _test_granular_accuracy(block, bs, dtype, config, delay_wgrad_compute=False,
out = block(inp_hidden_states)
if isinstance(out, (List, Tuple)):
out = out[0]
loss = out.sum()
loss.backward()
if grad_output is None:
loss = out.sum()
loss.backward()
else:
out.backward(grad_output)
if delay_wgrad_compute:
block.backward_dw()

Expand Down Expand Up @@ -2058,15 +2063,35 @@ def test_layernorm_accuracy(dtype, bs, model, eps, zero_centered_gamma):
assert_allclose(te_output, torch_output, atol[dtype], rtol[dtype])


@pytest.mark.parametrize("dtype", param_types)
@pytest.mark.parametrize("bs", batch_sizes)
@pytest.mark.parametrize("model", ["small"])
@pytest.mark.parametrize("normalization", all_normalizations)
@pytest.mark.parametrize("zero_centered_gamma", all_boolean)
@pytest.mark.parametrize("return_bias", all_boolean)
@pytest.mark.parametrize("bias", all_boolean)
@pytest.mark.parametrize(
"dtype,bs,model,normalization,zero_centered_gamma,return_bias,bias,split_storage",
[
(dtype, bs, "small", normalization, zero_centered_gamma, return_bias, bias, None)
for dtype in param_types
for bs in batch_sizes
for normalization in all_normalizations
for zero_centered_gamma in all_boolean
for return_bias in all_boolean
for bias in all_boolean
]
+ [
pytest.param(
torch.bfloat16,
1,
"small",
"LayerNorm",
False,
False,
True,
storage,
id=f"split-{storage}-storage",
marks=pytest.mark.skipif(not is_bf16_available(), reason="BF16 is not supported"),
)
for storage in ("shared", "separate")
],
)
def test_layernorm_linear_accuracy(
dtype, bs, model, normalization, zero_centered_gamma, return_bias, bias
dtype, bs, model, normalization, zero_centered_gamma, return_bias, bias, split_storage
):
config = model_configs[model]

Expand All @@ -2081,8 +2106,25 @@ def test_layernorm_linear_accuracy(
return_bias=return_bias,
bias=bias,
device="cuda",
parameters_split=(
dict(q=2 * config.hidden_size, k=config.hidden_size, v=config.hidden_size)
if split_storage
else None
),
)

te_module = te_ln_linear.te_module
weights = [getattr(te_module, name) for name in te_module.weight_names]
biases = [getattr(te_module, name) for name in te_module.bias_names] if bias else []
if split_storage:
for parts in (weights, biases):
if split_storage == "separate":
for part in parts:
part.data = part.detach().clone()
assert len({part.untyped_storage().data_ptr() for part in parts}) == (
len(parts) if split_storage == "separate" else 1
)

torch_ln_linear = (
TorchLayerNormLinear(
config.hidden_size,
Expand All @@ -2105,12 +2147,26 @@ def test_layernorm_linear_accuracy(
torch_ln_linear.layernorm.bias = Parameter(
te_ln_linear.te_module.layer_norm_bias.clone()
)
torch_ln_linear.linear.weight = Parameter(te_ln_linear.te_module.weight.clone())
torch_ln_linear.linear.weight = Parameter(torch.cat(weights))
if bias:
torch_ln_linear.linear.bias = Parameter(te_ln_linear.te_module.bias.clone())
torch_ln_linear.linear.bias = Parameter(torch.cat(biases))

te_outputs = _test_granular_accuracy(te_ln_linear, bs, dtype, config)
torch_outputs = _test_granular_accuracy(torch_ln_linear, bs, dtype, config)
grad_output = (
torch.randn(config.max_seqlen_q, bs, 4 * config.hidden_size, dtype=dtype, device="cuda")
if split_storage
else None
)
te_outputs = _test_granular_accuracy(te_ln_linear, bs, dtype, config, grad_output=grad_output)
torch_outputs = _test_granular_accuracy(
torch_ln_linear, bs, dtype, config, grad_output=grad_output
)
if split_storage:
torch_outputs = [
*torch_outputs[:-2],
*torch_outputs[-2].split(te_module.parameter_split_sizes),
*torch_outputs[-1].split(te_module.parameter_split_sizes),
]
assert len(te_outputs) == len(torch_outputs)

atol = {
torch.float32: 2.5e-4,
Expand Down
Loading
Loading