Skip to content

[Do not merge!] [Build] Migrate vendored DeepGEMM from pybind to TORCH_LIBRARY (abi3) - #48962

Open
cleonard530 wants to merge 8 commits into
vllm-project:mainfrom
cleonard530:deep_gemm_migration_to_torch_library
Open

[Do not merge!] [Build] Migrate vendored DeepGEMM from pybind to TORCH_LIBRARY (abi3)#48962
cleonard530 wants to merge 8 commits into
vllm-project:mainfrom
cleonard530:deep_gemm_migration_to_torch_library

Conversation

@cleonard530

@cleonard530 cleonard530 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Purpose

This PR continues the libtorch stable ABI migration (see #26946) for vLLM. Here, we are not migrating deep_gemm to the stable abi yet, but are moving it off of pybind and onto TORCH_LIBRARY. Once we make these updates, we will open a seperate PR to make deep_gemm torch ABI stable. This points to the DeepGEMM updates in the PR deepseek-ai/DeepGEMM#393

@janeyx99 @Harry-Chen

Test Plan

  python tools/check_wheel_deepgemm.py
  pytest -v -s tests/kernels/quantization/test_block_fp8.py
  pytest -v -s tests/kernels/moe/test_deepgemm.py
  pytest -v -s tests/kernels/moe/test_batched_deepgemm.py
  pytest -v -s tests/kernels/attention/test_deepgemm_attention.py

Test Result

  • tools/check_wheel_deepgemm.py - PASS
  • tests/kernels/quantization/test_block_fp8.py - 100 failed, 322 passed, all failures are fatal error: sanitizer/asan_interface.h: No such file or directory. Not related to TORCH_LIBRARY migration
  • tests/kernels/moe/test_deepgemm.py - PASS
  • tests/kernels/moe/test_batched_deepgemm.py - PASS
  • tests/kernels/attention/test_deepgemm_attention.py - PASS

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

Migration progress using the Audit Python extension torch-abi-audit:
Note, deep_gemm used to have uses-private-api instead of abi3-ok

 -- extensions --
    [STABLE  ] [abi3-ok               ] _C_stable_libtorch.abi3.so  (stable_shim=87, unstable=0)
    [STABLE  ] [abi3-ok               ] _flashmla_C.abi3.so  (stable_shim=65, unstable=0)
    [STABLE  ] [abi3-ok               ] _flashmla_extension_C.abi3.so  (stable_shim=63, unstable=0)
    [STABLE  ] [abi3-ok               ] _moe_C_stable_libtorch.abi3.so  (stable_shim=72, unstable=0)
    [NO-TORCH] [abi3-ok               ] cumem_allocator.abi3.so
    [NO-TORCH] [abi3-ok               ] fs_io_C.abi3.so
    [NO-TORCH] [abi3-ok               ] spinloop.abi3.so
--> [UNSTABLE] [abi3-ok               ] third_party/deep_gemm/_C_extension.abi3.so  (stable_shim=0, unstable=71)
    [UNSTABLE] [abi3-ok               ] vllm_flash_attn/_vllm_fa2_C.abi3.so  (stable_shim=0, unstable=85)
    [UNSTABLE] [abi3-ok               ] vllm_flash_attn/_vllm_fa3_C.abi3.so  (stable_shim=0, unstable=81)

@mergify mergify Bot added the ci/build label Jul 17, 2026
@cleonard530
cleonard530 marked this pull request as ready for review July 17, 2026 16:24

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

set(_dg_pythons "${Python_EXECUTABLE}")
endif()
message(STATUS "DeepGEMM _C will be built for: ${_dg_pythons}")
message(STATUS "DeepGEMM extension will be built with: ${Python_EXECUTABLE}")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This used to link private CPython symbols, so each python needed it's own C.cpython-3XY-….so.

Now, it builds against the CPython Limited/Stable ABI (Py_LIMITED_API), so one _C_extension.abi3.so works across supported CPythons.

FILES_MATCHING PATTERN "_C.cpython-*.so")
endforeach()
add_custom_target(_deep_gemm_C ALL DEPENDS ${_dg_markers})
set(_dg_dir "${CMAKE_CURRENT_BINARY_DIR}/deepgemm_C")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This block replaced the per-Python build loop with a single abi3 build

Comment thread tools/build_deepgemm_C.py
env.pop("DG_SKIP_CUDA_BUILD", None)

print(f"[build_deepgemm_C] building in {src} with {sys.executable}", flush=True)
subprocess.check_call(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Use deep_gemm's setup.py to build deep_gemm

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This call also gets Python_EXECUTABLE so building DeepGEMM's abi3 extension always tracks whatever Python vLLM is currently being built for.

required = required_pythons()
missing = [v for v in required if v not in found]
print(f"deepgemm _C: found {sorted(found)}, required {required}, missing {missing}")
sys.exit(1 if missing else 0)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This file used to check each required python version in pyproject.toml and failed if matching *.so python version weren't there.

f"deepgemm vendored binding: shim={shim.is_file()}, "
f"extensions={[p.name for p in so_files]}"
)
if missing:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Now, it checks vllm.third_party.deep_gemm to make sure the _C.py shim and _C_extension*.so are there.

@Harry-Chen Harry-Chen added the ready ONLY add when PR is ready to merge/full CI is needed label Jul 18, 2026
@Harry-Chen

Copy link
Copy Markdown
Member

Marked as ready to automatically trigger CI run.

@cleonard530

Copy link
Copy Markdown
Contributor Author

@Harry-Chen, the failure for these three test comes from this check
DG_DEVICE_ASSERT((values[j] & 0x807fffffu) == 0);

which was added between the previously tagged commit and my commit, but not directly due to the migration. We will need to figure out how to handle this before anything is merged (I don't think it will be difficult to fix), but I am planning on putting that off until we decide if we will be using upstream or the vllm-project/DeepGEMM, which doesn't have the check.

@Harry-Chen

Copy link
Copy Markdown
Member

@Harry-Chen, the failure for these three test comes from this check DG_DEVICE_ASSERT((values[j] & 0x807fffffu) == 0);

which was added between the previously tagged commit and my commit, but not directly due to the migration. We will need to figure out how to handle this before anything is merged (I don't think it will be difficult to fix), but I am planning on putting that off until we decide if we will be using upstream or the vllm-project/DeepGEMM, which doesn't have the check.

I see. I think currently we are using https://github.com/deepseek-ai/DeepGEMM/tree/nv_dev, which adds sm120 support (from NVIDIA) on top of upstream master.

@cleonard530

Copy link
Copy Markdown
Contributor Author

I see. I think currently we are using https://github.com/deepseek-ai/DeepGEMM/tree/nv_dev, which adds sm120 support (from NVIDIA) on top of upstream master.

Oh yes, you're right @Harry-Chen. Once we agree we are in a good spot, should we try to merge into this branch? Do you know how receptive the maintainers for this repo will be to our migration efforts?

CC @janeyx99

@Harry-Chen

Copy link
Copy Markdown
Member

I see. I think currently we are using https://github.com/deepseek-ai/DeepGEMM/tree/nv_dev, which adds sm120 support (from NVIDIA) on top of upstream master.

Oh yes, you're right @Harry-Chen. Once we agree we are in a good spot, should we try to merge into this branch? Do you know how receptive the maintainers for this repo will be to our migration efforts?

I have an issue there: deepseek-ai/DeepGEMM#333. But given the situation of the repo, I do not think we should put too much hope in upstream PRs. But since NVIDIA has their own branch on master, I do not know whether maintaining a fork would be a good idea.

CC @janeyx99

@cleonard530
cleonard530 force-pushed the deep_gemm_migration_to_torch_library branch from 255e87e to bd62abb Compare July 24, 2026 14:05
@@ -234,7 +224,8 @@ def _deepgemm_fp8_gemm_nt_warmup(

device = w.device
a1q = torch.empty((max_tokens, k), device=device, dtype=torch.float8_e4m3fn)
a1q_scales = torch.empty(
# Must be a power of two (UE8M0 packing asserts zero sign/mantissa bits).
a1q_scales = torch.ones(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not related to the TORCH_LIBRARY migration — a separate pre-existing bug. torch.empty left a1q_scales uninitialized, occasionally tripping DeepGEMM's UE8M0 assert (scales must be exact powers of two). Switched to torch.ones; warmup output is discarded, so this has no effect on real inference.

@cleonard530
cleonard530 force-pushed the deep_gemm_migration_to_torch_library branch 2 times, most recently from 1c2538e to e98f4cf Compare July 24, 2026 17:56
@cleonard530

Copy link
Copy Markdown
Contributor Author

@Harry-Chen, I opened a PR upstream on the nv_dev branch, deepseek-ai/DeepGEMM#393. Please let me know if you think this is the right move and if you know anyone who might be able to review it to help get it through. If there is no response there, then the only other option I can think of is using the https://github.com/vllm-project/DeepGEMM fork, which I know we don't want to have to maintain.

@mergify

mergify Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @cleonard530.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Jul 30, 2026
Signed-off-by: Chris Leonard <chleonar@redhat.com>
…py only needs SRC and OUT; update the cmake call to match.

Signed-off-by: Chris Leonard <chleonar@redhat.com>
Signed-off-by: Chris Leonard <chleonar@redhat.com>
Signed-off-by: Chris Leonard <chleonar@redhat.com>
…epgemm.sh git tag

Signed-off-by: Chris Leonard <chleonar@redhat.com>
Signed-off-by: Chris Leonard <chleonar@redhat.com>
… parameter to a mutable parameter

Signed-off-by: Chris Leonard <chleonar@redhat.com>
torch.empty leaves a1q_scales as garbage, which fails DeepGEMM's UE8M0
assert that scales be exact powers of two. Use torch.ones instead;
warmup output is discarded, so this is a no-op for real inference.
Unrelated to the TORCH_LIBRARY migration — a pre-existing bug in the
branch beyond the last pinned git tag.

Signed-off-by: Chris Leonard <chleonar@redhat.com>
@cleonard530
cleonard530 force-pushed the deep_gemm_migration_to_torch_library branch from e98f4cf to 2e77b11 Compare July 31, 2026 18:29
@mergify mergify Bot removed the needs-rebase label Jul 31, 2026
@mergify

mergify Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @cleonard530.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/build needs-rebase ready ONLY add when PR is ready to merge/full CI is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants