-
Notifications
You must be signed in to change notification settings - Fork 56
[Spyre-Next] SpyreSiluAndMul Tests #863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
9e04728
3c9870d
be40072
cbe619d
2170c8c
e4ea1e1
c1ae1a9
fae251f
c488086
c7b9935
4af0718
acf08fc
6e6fbae
bb114d2
ed78b8f
8122cd8
124f89d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| """ | ||
| Test SpyreSiluAndMul custom op correctness against a reference implementation. | ||
| """ | ||
|
|
||
| import pytest | ||
| import torch | ||
|
|
||
| @pytest.fixture | ||
| def dummy_tensor(): | ||
| return torch.randn(4, 256, dtype=torch.float32) # 2*d=256, so d=128 | ||
|
|
||
|
|
||
| def mock_forward_native(x): | ||
| """Mock: return ones with output shape (halves last dim).""" | ||
| d = x.shape[-1] // 2 | ||
| return torch.ones(x.shape[:-1] + (d,), dtype=x.dtype, device=x.device) | ||
|
|
||
|
|
||
| @pytest.mark.spyre | ||
| @pytest.mark.siluandmul | ||
| def test_siluandmul_oot_dispatch(default_vllm_config, monkeypatch, dummy_tensor): | ||
| """Verify SiluAndMul OOT registration: class swap and forward_oot routing.""" | ||
| from vllm.model_executor.layers.activation import SiluAndMul | ||
| from vllm_spyre_next.custom_ops.silu_and_mul import SpyreSiluAndMul | ||
|
|
||
| layer = SiluAndMul() | ||
|
|
||
| # OOT class swap: SiluAndMul.__new__ should produce SpyreSiluAndMul | ||
| assert isinstance(layer, SpyreSiluAndMul) | ||
|
|
||
| # dispatch_forward should have selected forward_oot | ||
| assert layer._forward_method == layer.forward_oot | ||
|
|
||
| # Mock forward_native (called by forward_oot) with a known transform | ||
| monkeypatch.setattr(layer, "forward_native", mock_forward_native) | ||
| out = layer.forward_oot(dummy_tensor) | ||
|
|
||
| # Expected: ones with shape [4, 128] (halved last dim) | ||
| expected = torch.ones(4, 128, dtype=dummy_tensor.dtype) | ||
| assert torch.allclose(out, expected) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -526,6 +526,28 @@ def sort_key(item: pytest.Item) -> tuple[int, int]: | |
| items.sort(key=sort_key) | ||
|
|
||
|
|
||
| def _convert_yaml_value(value): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is added for future compatibility in case we want to override the torch data types |
||
| """Convert YAML string values to Python objects where appropriate. | ||
|
|
||
| Handles torch dtype strings like "torch.half" -> torch.half. | ||
| """ | ||
| if isinstance(value, str): | ||
| import torch | ||
|
|
||
| dtype_map = { | ||
| "torch.half": torch.half, | ||
| "torch.float16": torch.float16, | ||
| "torch.bfloat16": torch.bfloat16, | ||
| "torch.float32": torch.float32, | ||
| "torch.float": torch.float, | ||
| "torch.float64": torch.float64, | ||
| "torch.double": torch.double, | ||
| } | ||
| if value in dtype_map: | ||
| return dtype_map[value] | ||
| return value | ||
|
|
||
|
|
||
| @pytest.hookimpl(tryfirst=True) | ||
| def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: | ||
| """Apply parameter overrides from YAML config.""" | ||
|
|
@@ -554,7 +576,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: | |
| for i, marker in enumerate(metafunc.definition.own_markers): | ||
| if marker.name == "parametrize" and marker.args[0] == po.param_name: | ||
| metafunc.definition.own_markers[i] = pytest.mark.parametrize( | ||
| po.param_name, list(po.values) | ||
| po.param_name, [_convert_yaml_value(v) for v in po.values] | ||
| ).mark | ||
| break | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,18 @@ tests: | |
| # hidden_size: [64] | ||
| # block_list: | ||
| # - test: "test_fused_rms_norm_quant" | ||
| - rel_path: tests/kernels/core/test_activation.py | ||
| allow_list: | ||
| - test: "test_act_and_mul" | ||
| mode: mandatory_pass | ||
| tags: [siluandmul, upstream] | ||
| params: | ||
| allow: | ||
| activation: [silu_and_mul] | ||
| override: | ||
| num_tokens: [7, 83, 1024] | ||
| d: [8, 64, 128, 1024] | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is failing for odd values of As far as numerical correctness goes, we are good to go |
||
| device: [cpu] | ||
| - rel_path: tests/models/language/generation/test_common.py | ||
| allow_list: | ||
| - test: "test_models" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we still need this file if we reuse the upstream tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might still need to check for
forward_ootdispatch, but other tests can go