DSA: probe Paddle, not sys.modules["torch"], for framework metadata - #13
Merged
sneaxiy merged 1 commit intoSep 4, 2026
Merged
Conversation
1.28.0's framework-neutral refactor reads dtypes, devices, strides and the
current stream through ``sys.modules.get("torch")``. That probe is wrong on this
branch: ``paddle.enable_compat(scope={"cudnn"})`` rewrites only the module-level
``import torch`` of the modules it loads and never puts the shim in
``sys.modules``, while a real PyTorch is routinely installed alongside Paddle in
the same environment -- so the probe returns real torch and every Paddle tensor
is misclassified.
Symptoms this fixes, all of them on the DSA path:
* ``APIBase._check_dtype`` took the "not a dtype" branch for every Paddle dtype
(``isinstance(paddle.bfloat16, torch.dtype)`` is False) and raised
``ValueError: Expected dtype to be a torch.dtype or list, got
<class 'paddle.dtype'>`` from ``check_support()``. Both indexer backward
wrappers were unusable; ~60 PaddleFleet DSA/indexer tests failed.
* ``tensor_adapter.detect_framework`` returned "unknown" for Paddle tensors, so
``default_stream`` handed back the CUDA legacy default stream instead of
Paddle's current stream, and ``get_strides`` fell through to a C-contiguous
guess.
* ``_raw_stream``/``_get_default_stream`` read ``.cuda_stream`` off the Stream
object; Paddle exposes the raw handle as ``stream_base.raw_stream`` (the same
handle ``deepseek_sparse_attention/utils/runtime.resolve_stream`` uses).
* ``TensorDesc.is_contiguous`` dereferenced ``torch.contiguous_format``
unconditionally, which Paddle does not define; look the formats up
defensively so the default (``memory_format=None``) path cannot break.
ForFishes
force-pushed
the
paddle/v1.28.0-fix-framework-probe
branch
from
September 3, 2026 17:08
0f2cada to
267d853
Compare
sneaxiy
approved these changes
Sep 4, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Follow-up to #12. 1.28.0's framework-neutral metadata refactor (
python/cudnn/tensor_adapter.py, plus the_torch()helper inpython/cudnn/api_base.py) identifies the framework withsys.modules.get("torch"). That probe does not work on this branch, and the failure is not subtle: both DSA indexer backward wrappers are unusable.Why the probe fails here
paddle.enable_compat(scope={"cudnn"})rewrites only the module-levelimport torchof the modules it loads — it never registers the shim insys.modules. Meanwhile a real PyTorch is routinely installed alongside Paddle in the same environment (in ours: PyTorch 2.12 + Paddle 3.4). Sosys.modules["torch"]resolves to real PyTorch, which describes neither Paddle's dtypes nor its devices, strides or current stream.Note that a function-level
import torchdoes not help either, for the same reason — the fix has to name Paddle explicitly.Symptoms fixed
APIBase._check_dtypetook its "not a dtype" branch for every Paddle dtype, becauseisinstance(paddle.bfloat16, torch.dtype)isFalsefor realtorch:This fires in
check_support(), i.e. beforecompile()/execute(), soindexer_backward_wrapperanddense_indexer_backward_wrapperboth fail unconditionally. In our downstream test suite that was ~60 failing DSA/indexer tests.tensor_adapter.detect_frameworkreturned"unknown"for Paddle tensors. Two silent downgrades follow:default_streamhanded back the CUDA legacy default stream instead of Paddle's current stream (a correctness hazard for anything overlapping with framework work), andget_stridesfell through to a C-contiguous guess instead of reading the real strides._raw_stream/_get_default_streamread.cuda_streamoff the stream object. Paddle exposes the raw handle asstream_base.raw_stream— the same handledeepseek_sparse_attention/utils/runtime.resolve_streamalready uses, so the two now agree.TensorDesc.is_contiguousdereferencedtorch.contiguous_formatunconditionally; Paddle does not define it. The formats are now looked up defensively so the default (memory_format=None) path cannot break.Verification
Downstream (PaddleFleet DSA/indexer/CSA, single card, B30Z sm_103), 22 test files:
test_cudnn_dsa_indexer_bwd16 failed / 19 passed,test_hybrid_mla_warmup_kl_cudnn28 failed / 5 passed,test_mqa_latent_attention8 failed,test_indexer_loss_overlap5 failed,test_block_sparse_dsa_gradcheck13 failed,test_hysparse_mqa_gather_dsa6 failed,test_cudnn_dsa_indexer_docmask3 failed;paddle/v1.27.0, so it is unrelated to 1.28.0.We also added a host-side regression test downstream that asserts the probe resolves to Paddle, that
_check_dtypeaccepts Paddle dtypes in both scalar and list form, that Paddle tensors are recognised by the adapter, that strides are read rather than guessed, and thatdefault_streammatches Paddle's current stream. Four of its seven cases fail without this patch.Perf on the same setup is unaffected by this patch; for the record,
paddle/v1.28.0is a solid win overpaddle/v1.27.0on the sparse DSA indexer backward at our production shape (b=1, s_q=s_k=8192, h=64, d=128, topk=2048): 4.757 ms -> 3.095 ms end to end.pre-commit(black, line length 160) is clean.