diff --git a/flash_mla/__init__.py b/flash_mla/__init__.py index 02a8bbab..229746f3 100644 --- a/flash_mla/__init__.py +++ b/flash_mla/__init__.py @@ -1,4 +1,8 @@ -__version__ = "1.0.0" +try: + from importlib.metadata import version as _get_version + __version__ = _get_version("flash_mla") +except (ImportError, ModuleNotFoundError): + from flash_mla._version import __version__ from flash_mla.flash_mla_interface import ( get_mla_metadata, diff --git a/flash_mla/_version.py b/flash_mla/_version.py new file mode 100644 index 00000000..5becc17c --- /dev/null +++ b/flash_mla/_version.py @@ -0,0 +1 @@ +__version__ = "1.0.0" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..21a4c2ae --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["setuptools>=61.0"] +# torch is NOT listed above because pip's isolated build would pull a CPU-only +# wheel from PyPI, which lacks CUDA support. FlashMLA requires a CUDA-capable +# torch pre-installed in the target environment before building. +build-backend = "setuptools.build_meta" + +[project] +name = "flash_mla" +dynamic = ["version"] +description = "DeepSeek's library of optimized attention kernels, powering DeepSeek-V3 and DeepSeek-V3.2-Exp models" +readme = "README.md" +license = {text = "MIT"} +authors = [ + {name = "DeepSeek"}, +] +requires-python = ">=3.8" +dependencies = [ + "torch", +] +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] + +[project.urls] +Homepage = "https://github.com/deepseek-ai/FlashMLA" +Repository = "https://github.com/deepseek-ai/FlashMLA" + +# [tool.setuptools.dynamic] is intentionally omitted. +# Version is computed in setup.py (base from flash_mla/_version.py + git hash). +# The attr directive is unusable here: importing any flash_mla submodule +# triggers __init__.py, which imports the C extension that is not yet built. diff --git a/setup.py b/setup.py index 513b4355..82bc176b 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,14 @@ def get_nvcc_thread_args(): this_dir = os.path.dirname(os.path.abspath(__file__)) +# Read base version from _version.py without importing the flash_mla package. +# Python always executes __init__.py first when importing any submodule, +# and flash_mla/__init__.py imports the C extension which is not yet built. +_ver_ns = {} +with open(os.path.join(this_dir, "flash_mla", "_version.py")) as f: + exec(f.read(), _ver_ns) +__base_version__ = _ver_ns.get("__version__", "1.0.0") + if IS_WINDOWS: cxx_args = ["/O2", "/std:c++20", "/DNDEBUG", "/W0"] else: @@ -144,7 +152,7 @@ def get_nvcc_thread_args(): setup( name="flash_mla", - version="1.0.0" + rev, + version=__base_version__ + rev, packages=find_packages(include=['flash_mla']), ext_modules=ext_modules, cmdclass={"build_ext": BuildExtension},