forked from deepseek-ai/FlashMLA
-
Notifications
You must be signed in to change notification settings - Fork 6
校验 Python API 输入参数 #22
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
Open
ghangz
wants to merge
2
commits into
MetaX-MACA:main
Choose a base branch
from
ghangz:mengz/validate-python-api-inputs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,86 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import types | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import pytest | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import torch | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| class _FakeFlashMla(types.SimpleNamespace): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| def get_mla_metadata(self, *args, **kwargs): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def fwd_kvcache_mla(self, *args, **kwargs): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return torch.empty(1), torch.empty(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.modules.setdefault("flash_mla_cuda", _FakeFlashMla()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| from flash_mla.flash_mla_interface import flash_mla_with_kvcache # noqa: E402 | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def _valid_inputs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q = torch.empty(2, 1, 4, 8) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| k_cache = torch.empty(8, 16, 1, 8) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| block_table = torch.zeros(2, 4, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cache_seqlens = torch.ones(2, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata = torch.zeros(1, 8, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| num_splits = torch.zeros(3, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return q, k_cache, block_table, cache_seqlens, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_mismatched_batch_size(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cache_seqlens = torch.ones(3, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(ValueError, match="batch size"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, 4, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_non_int32_cache_lengths(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cache_seqlens = cache_seqlens.to(torch.int64) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(TypeError, match="cache_seqlens"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, 4, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_bad_num_splits_length(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, _num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| num_splits = torch.zeros(2, dtype=torch.int32) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(ValueError, match="num_splits must have size"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, 4, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_non_tensor_inputs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(TypeError, match="block_table must be a torch.Tensor"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table.tolist(), cache_seqlens, 4, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_cross_device_inputs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
| block_table = block_table.to("meta") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(ValueError, match="same device"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, 4, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_flash_mla_rejects_invalid_value_head_dim(): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, metadata, num_splits = _valid_inputs() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(ValueError, match="head_dim_v"): | ||||||||||||||||||||||||||||||||||||||||||||||||||
| flash_mla_with_kvcache( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| q, k_cache, block_table, cache_seqlens, 16, metadata, num_splits | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+80
to
+86
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. 为了确保新增的
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
PR 描述中提到“对非法 dtype、shape 或设备输入给出明确错误”,但目前的实现中并没有对设备(Device)一致性进行校验。如果用户传入了位于不同设备(例如 CPU 和 CUDA,或者不同的 GPU 卡)上的 Tensor,可能会导致底层算子运行时报错或产生未定义行为。此外,如果传入的参数不是
torch.Tensor类型(例如普通的 list 或 numpy 数组),直接访问.dim()或.dtype会抛出混淆的AttributeError。建议在函数开头增加对所有输入 Tensor 的类型和设备一致性校验。