diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000000..c17cc8f7b014 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,22 @@ +.git +.gitignore +.pytest_cache +.ruff_cache +__pycache__ +*.py[cod] +build +dist +*.egg-info +vllm_musa.egg-info +.coverage +htmlcov + +# setup.py clones and pins third_party sources inside the image. Copying a local +# checkout makes the build context large and can hide drift from the pinned refs. +third_party/vllm +third_party/flashinfer + +# Local/editor artifacts. +.claude +.humanize +assets diff --git a/README.md b/README.md index 132b169a8777..b686a36ba03e 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ The plugin leverages the following key components: | vLLM Version | PyTorch Version | Engine | Status | |--------------|-----------------|---------|--------------| -| v0.22.0 | 2.7.1 | V1 only | ✅ Supported | +| v0.22.0 | 2.9.x | V1 only | ✅ Supported | > **Note**: This plugin uses vLLM's V1 engine architecture. V0 engine is not supported. @@ -57,7 +57,15 @@ The plugin leverages the following key components: cd vllm-musa ``` -2. Install vLLM Hardware Plugin for Moore Threads MUSA: +2. Install Python dependencies before installing `vllm-musa`. The MUSA + requirements entrypoint includes common dependencies and MUSA-private pins + such as `torch` and `torch_musa`. + + ```bash + pip install -r requirements/build.txt -r requirements/musa.txt + ``` + +3. Install vLLM Hardware Plugin for Moore Threads MUSA: ```bash # Standard installation (installs vLLM MUSA plugin and vLLM) @@ -67,7 +75,7 @@ The plugin leverages the following key components: pip install -e . --no-build-isolation -v ``` -3. Verify the installation: +4. Verify the installation: ```bash # Check plugin registration @@ -105,6 +113,7 @@ Useful commands: ```bash ccache --zero-stats +pip install -r requirements/build.txt -r requirements/musa.txt pip install -e . --no-build-isolation -v ccache --show-stats ``` diff --git a/README_CN.md b/README_CN.md index 370ef26dd085..e0ce5f95ad68 100644 --- a/README_CN.md +++ b/README_CN.md @@ -44,7 +44,7 @@ | vLLM 版本 | PyTorch 版本 | 引擎 | 状态 | |-----------|--------------|---------|--------------| -| v0.22.0 | 2.7.1 | 仅 V1 | ✅ 已支持 | +| v0.22.0 | 2.9.x | 仅 V1 | ✅ 已支持 | > **注意**:本插件使用 vLLM 的 V1 引擎架构,不支持 V0 引擎。 @@ -57,7 +57,14 @@ cd vllm-musa ``` -2. 安装摩尔线程 MUSA 的 vLLM 硬件插件: +2. 安装 `vllm-musa` 前先安装 Python 依赖。MUSA requirements 入口包含通用依赖 + 和 `torch`、`torch_musa` 等 MUSA private 版本约束: + + ```bash + pip install -r requirements/build.txt -r requirements/musa.txt + ``` + +3. 安装摩尔线程 MUSA 的 vLLM 硬件插件: ```bash # 标准安装(安装 vLLM MUSA 插件和 vLLM) @@ -67,7 +74,7 @@ pip install -e . --no-build-isolation -v ``` -3. 验证安装: +4. 验证安装: ```bash # 检查插件注册 diff --git a/docker/build_image.sh b/docker/build_image.sh new file mode 100755 index 000000000000..d2c1b258eaef --- /dev/null +++ b/docker/build_image.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +cd "${REPO_ROOT}" + +PYTHON_VERSION="${PYTHON_VERSION:-3.10}" +BASE_IMAGE="${BASE_IMAGE:-ubuntu:22.04}" + +MUSA_APT_SOURCE="${MUSA_APT_SOURCE:-https://dl.mthreads.com/repo/repository/ubuntu2204/}" +INSTALL_MUSA_STACK="${INSTALL_MUSA_STACK:-auto}" +MUSA_RUNTIME_VERSION="${MUSA_RUNTIME_VERSION:-5.1}" +MCCL_VERSION="${MCCL_VERSION:-2.3.0}" + +PYTORCH_RELEASE="$( + awk -F'==' '/^torch==/ {gsub(/\.\*/, "", $2); print $2; exit}' \ + requirements/musa_private.txt +)" +if [[ -z "${PYTORCH_RELEASE}" ]]; then + echo "Failed to derive PyTorch release from requirements/musa_private.txt" >&2 + exit 1 +fi + +BUILD_MOONCAKE="${BUILD_MOONCAKE:-1}" +MOONCAKE_REPO="${MOONCAKE_REPO:-https://github.com/kvcache-ai/Mooncake.git}" +MOONCAKE_COMMIT="${MOONCAKE_COMMIT:-b6a841dc78c707ec655a563453277d969fb8f38d}" + +IMAGE_REPOSITORY="${IMAGE_REPOSITORY:-vllm-musa}" +IMAGE_FLAVOR="${IMAGE_FLAVOR:-ubuntu22.04_py${PYTHON_VERSION}_musa_runtime_${MUSA_RUNTIME_VERSION}_pytorch_release_${PYTORCH_RELEASE}}" +IMAGE_TAG="${IMAGE_TAG:-${IMAGE_REPOSITORY}:${IMAGE_FLAVOR}}" + +docker build \ + --network host \ + -f docker/musa.Dockerfile \ + -t "${IMAGE_TAG}" \ + --build-arg BASE_IMAGE="${BASE_IMAGE}" \ + --build-arg PYTHON_VERSION="${PYTHON_VERSION}" \ + --build-arg MUSA_APT_SOURCE="${MUSA_APT_SOURCE}" \ + --build-arg INSTALL_MUSA_STACK="${INSTALL_MUSA_STACK}" \ + --build-arg MUSA_RUNTIME_VERSION="${MUSA_RUNTIME_VERSION}" \ + --build-arg MCCL_VERSION="${MCCL_VERSION}" \ + --build-arg BUILD_MOONCAKE="${BUILD_MOONCAKE}" \ + --build-arg MOONCAKE_REPO="${MOONCAKE_REPO}" \ + --build-arg MOONCAKE_COMMIT="${MOONCAKE_COMMIT}" \ + "$@" \ + . diff --git a/docker/musa.Dockerfile b/docker/musa.Dockerfile new file mode 100644 index 000000000000..553c6c205bd4 --- /dev/null +++ b/docker/musa.Dockerfile @@ -0,0 +1,319 @@ +# Formal vllm-musa image definition for Ubuntu 22.04 and the public MUSA apt +# stack. +# +# This file intentionally keeps the release flow separate from temporary +# validation package URLs. Do not add validation-only wheel/tar download-and- +# extract logic back here. + +ARG BASE_IMAGE=ubuntu:22.04 +ARG PYTHON_VERSION=3.10 + +FROM ${BASE_IMAGE} AS base + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +ARG PYTHON_VERSION + +# torch_musa uses "31"; MATE 0.2.3 parses dotted arch tokens such as "3.1". +ENV DEBIAN_FRONTEND=noninteractive \ + PIP_CACHE_DIR=/root/.cache/pip \ + PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PYTHONUNBUFFERED=1 \ + MUSA_HOME=/usr/local/musa \ + MTHREADS_VISIBLE_DEVICES=all \ + MTGPU_TARGET=mp_31 \ + TORCH_MUSA_ARCH_LIST=31 \ + MATE_MUSA_ARCH_LIST=3.1 +ENV PATH=/usr/local/mtshmem/bin:${MUSA_HOME}/bin:${MUSA_HOME}/mudnn/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/mtshmem/lib:${MUSA_HOME}/lib:${MUSA_HOME}/mudnn/lib:/usr/local/lib + +FROM base AS apt_base + +ARG PYTHON_VERSION + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + bash \ + build-essential \ + ca-certificates \ + ccache \ + cmake \ + curl \ + g++-12 \ + gcc-12 \ + git \ + git-lfs \ + gnupg \ + infiniband-diags \ + libcurl4-openssl-dev \ + libdrm2 \ + libibverbs-dev \ + libmkl-core \ + libmkl-gnu-thread \ + libmkl-intel-lp64 \ + libnuma1 \ + libomp-dev \ + libopenblas-base \ + libopenmpi-dev \ + librdmacm-dev \ + libssl-dev \ + libstdc++-12-dev \ + libtool \ + libyaml-dev \ + lsb-release \ + lsof \ + make \ + ninja-build \ + numactl \ + openmpi-bin \ + openssh-client \ + pkg-config \ + python${PYTHON_VERSION} \ + python${PYTHON_VERSION}-dev \ + python3-pip \ + python-is-python3 \ + rdma-core \ + unzip \ + xz-utils \ + zip && \ + python -m pip install --upgrade pip && \ + rm -rf /var/lib/apt/lists/* + +# The torch 2.9.x MUSA wheel links MKL with .so.2 sonames. Ubuntu 22.04 apt +# ships the same logical MKL components without that suffix. +RUN ln -sf /usr/lib/x86_64-linux-gnu/libmkl_intel_lp64.so \ + /usr/lib/x86_64-linux-gnu/libmkl_intel_lp64.so.2 && \ + ln -sf /usr/lib/x86_64-linux-gnu/libmkl_gnu_thread.so \ + /usr/lib/x86_64-linux-gnu/libmkl_gnu_thread.so.2 && \ + ln -sf /usr/lib/x86_64-linux-gnu/libmkl_core.so \ + /usr/lib/x86_64-linux-gnu/libmkl_core.so.2 && \ + ldconfig + +FROM apt_base AS runtime + +ARG MUSA_APT_SOURCE=https://dl.mthreads.com/repo/repository/ubuntu2204/ +ARG INSTALL_MUSA_STACK=auto +ARG MUSA_RUNTIME_VERSION=5.1 +ARG MCCL_VERSION=2.3.0 + +# The MUSA SDK/runtime stack is installed only from the configured apt source. +# MUSA_RUNTIME_VERSION is the single runtime-version selector. It accepts a +# major.minor version line such as 5.1, 5.2, 5.3, or 6.0 and derives versioned +# apt package names such as musa-toolkit-5-1 from it. Keep all MUSA SDK/runtime +# packages on that version line unless a package has an independent ABI +# constraint such as MCCL_VERSION. +RUN printf 'deb [trusted=true] %s jammy main\n' "${MUSA_APT_SOURCE}" \ + > /etc/apt/sources.list.d/musa.list && \ + if [[ "${INSTALL_MUSA_STACK}" == "0" ]]; then \ + echo "Skipping MUSA apt stack install because INSTALL_MUSA_STACK=0"; \ + exit 0; \ + fi && \ + if [[ "${INSTALL_MUSA_STACK}" == "auto" ]] && command -v mcc >/dev/null 2>&1; then \ + echo "Keeping MUSA stack from BASE_IMAGE"; \ + mcc --version || true; \ + exit 0; \ + fi && \ + apt-get update && \ + if [[ "${MUSA_RUNTIME_VERSION}" =~ ^([0-9]+)\.([0-9]+)(\.|$) ]]; then \ + runtime_major="${BASH_REMATCH[1]}"; \ + runtime_minor="${BASH_REMATCH[2]}"; \ + runtime_suffix="${runtime_major}-${runtime_minor}"; \ + else \ + echo "MUSA_RUNTIME_VERSION must start with ., got ${MUSA_RUNTIME_VERSION}" >&2; \ + exit 1; \ + fi && \ + musa_toolkit_packages=("musa-toolkit-${runtime_suffix}" musa-toolkit) && \ + mudnn_packages=(mudnn "libmudnn3-musa-${runtime_major}") && \ + musa_mualg_packages=("musa-mualg-${runtime_suffix}" musa-mualg) && \ + musa_muthrust_packages=("musa-muthrust-${runtime_suffix}" musa-muthrust) && \ + apt-cache policy \ + "${musa_toolkit_packages[@]}" \ + libmthreads-compute \ + "${mudnn_packages[@]}" \ + mccl-s5000 libmthreads-mtml \ + "${musa_mualg_packages[@]}" \ + "${musa_muthrust_packages[@]}" || true && \ + resolve_apt_package() { \ + local logical="$1"; \ + local versions="$2"; \ + local allow_unversioned="$3"; \ + shift 3; \ + local spec=""; \ + local version pkg found_version; \ + for version in ${versions}; do \ + for pkg in "$@"; do \ + if ! apt-cache show "${pkg}" >/dev/null 2>&1; then \ + continue; \ + fi; \ + found_version="$(apt-cache madison "${pkg}" | awk -v wanted="${version}" '$3 ~ "^" wanted {print $3; exit}')"; \ + if [[ -n "${found_version}" ]]; then \ + spec="${pkg}=${found_version}"; \ + break 2; \ + fi; \ + done; \ + done; \ + if [[ -z "${spec}" && "${allow_unversioned}" == "1" ]]; then \ + for pkg in "$@"; do \ + if apt-cache show "${pkg}" >/dev/null 2>&1; then \ + spec="${pkg}"; \ + break; \ + fi; \ + done; \ + fi; \ + if [[ -z "${spec}" ]]; then \ + echo "No apt package found for ${logical} with versions [${versions}]; checked: $*" >&2; \ + return 1; \ + fi; \ + echo "${spec}"; \ + } && \ + install_apt_package() { \ + local logical="$1"; \ + local versions="$2"; \ + local allow_unversioned="$3"; \ + shift 3; \ + local spec; \ + spec="$(resolve_apt_package "${logical}" "${versions}" "${allow_unversioned}" "$@")"; \ + echo "Installing ${logical}: ${spec}"; \ + apt-get install -y --allow-downgrades --no-install-recommends "${spec}"; \ + } && \ + install_apt_package musa-toolkit \ + "${MUSA_RUNTIME_VERSION}" \ + 0 "${musa_toolkit_packages[@]}" && \ + install_apt_package libmthreads-compute \ + "${MUSA_RUNTIME_VERSION}" \ + 0 libmthreads-compute && \ + install_apt_package mudnn "" 1 "${mudnn_packages[@]}" && \ + install_apt_package mccl-s5000 "${MCCL_VERSION}" 0 mccl-s5000 && \ + install_apt_package libmthreads-mtml "" 1 libmthreads-mtml && \ + install_apt_package musa-mualg "" 1 "${musa_mualg_packages[@]}" && \ + install_apt_package musa-muthrust "" 1 "${musa_muthrust_packages[@]}" && \ + printf '%s\n' \ + "${MUSA_HOME}/lib" \ + "${MUSA_HOME}/mudnn/lib" \ + "/usr/local/mtshmem/lib" \ + "/usr/lib/x86_64-linux-gnu" \ + > /etc/ld.so.conf.d/musa-runtime.conf && \ + ldconfig && \ + rm -rf /var/lib/apt/lists/* + +FROM runtime AS mooncake + +ARG BUILD_MOONCAKE=1 +ARG MOONCAKE_REPO=https://github.com/kvcache-ai/Mooncake.git +ARG MOONCAKE_COMMIT=b6a841dc78c707ec655a563453277d969fb8f38d + +ENV PATH=/usr/local/go/bin:${PATH} + +# Mooncake is a standalone component. Follow the SGLang ROCm source-build shape +# and the MUSA-specific CMake flags from /tmp/musa.Dockerfile. Do not route this +# stage through vllm-musa Python package index arguments. +RUN if [[ "${BUILD_MOONCAKE}" == "1" ]]; then \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + autoconf \ + ethtool \ + ibverbs-utils \ + openssh-server \ + perftest \ + rdmacm-utils \ + wget && \ + rm -rf /var/lib/apt/lists/* && \ + git clone "${MOONCAKE_REPO}" /workspace/Mooncake && \ + cd /workspace/Mooncake && \ + git checkout "${MOONCAKE_COMMIT}" && \ + git submodule update --init --recursive && \ + bash dependencies.sh -y && \ + mkdir -p build && \ + cd build && \ + cmake .. \ + -DBUILD_UNIT_TESTS=OFF \ + -DUSE_HTTP=ON \ + -DUSE_ETCD=ON \ + -DUSE_MUSA=ON \ + -DSTORE_USE_ETCD=ON \ + -DCMAKE_BUILD_TYPE=Release && \ + cmake --build . -j"$(nproc)" && \ + cmake --install . && \ + cd /workspace/Mooncake && \ + mkdir -p build/mooncake-transfer-engine/nvlink-allocator && \ + cd mooncake-transfer-engine/nvlink-allocator && \ + bash build.sh --use-mcc ../../build/mooncake-transfer-engine/nvlink-allocator/ && \ + cd /workspace/Mooncake && \ + OUTPUT_DIR=dist ./scripts/build_wheel.sh && \ + python -m pip install --no-cache-dir dist/*.whl && \ + rm -rf /workspace/Mooncake /root/.cache/pip /tmp/pip-*; \ + elif [[ "${BUILD_MOONCAKE}" == "0" ]]; then \ + echo "Skipping Mooncake build because BUILD_MOONCAKE=0"; \ + else \ + echo "Unsupported BUILD_MOONCAKE=${BUILD_MOONCAKE}" >&2; \ + exit 1; \ + fi + +FROM mooncake AS vllm_musa_deps + +# vllm-musa Python dependencies are installed before copying the full source +# tree so dependency layers can be reused. requirements/musa.txt is the MUSA +# platform entrypoint and includes requirements/musa_private.txt plus +# requirements/common.txt, matching the MetaX maca.txt/maca_private.txt pattern. +# torch, torch_musa, MATE, flash_attn_3, flash_mla, deep-gemm, tilelang_musa, +# TVM FFI, and torch_c_dlpack_ext must resolve from configured official pip +# indexes. No temporary OSS archives are unpacked in this formal Dockerfile. +COPY requirements/ /workspace/vllm-musa/requirements/ +WORKDIR /workspace/vllm-musa + +RUN python -m pip install \ + -r requirements/build.txt \ + -r requirements/musa.txt + +FROM vllm_musa_deps AS final + +COPY . /workspace/vllm-musa +RUN python -m pip install \ + -e . --no-build-isolation -v && \ + python -m pip install numpy==1.26 + +RUN python - <<'PY' +import importlib +import re +from pathlib import Path +from importlib.metadata import version + +def requirement_prefix(dist_name): + pattern = re.compile(rf"^{re.escape(dist_name)}==(.+)$") + for line in Path("requirements/musa_private.txt").read_text().splitlines(): + match = pattern.match(line.strip()) + if match: + return match.group(1).split("*", 1)[0] + raise RuntimeError(f"missing {dist_name} pin in requirements/musa_private.txt") + +expected = ( + ("numpy", "numpy", "1.26."), + ("torch", "torch", requirement_prefix("torch")), + ("torch_musa", "torch_musa", requirement_prefix("torch_musa")), + ("mate", "mate", ""), + ("flash_attn_3", "flash_attn_3", ""), + ("flash_mla", "flash_mla", ""), + ("deep-gemm", "deep_gemm", ""), + ("tilelang_musa", "tilelang", ""), + ("apache-tvm-ffi", "tvm_ffi", ""), + ("torch_c_dlpack_ext", "torch_c_dlpack_ext", ""), +) + +for dist_name, module_name, prefix in expected: + module = importlib.import_module(module_name) + installed = version(dist_name) + if prefix and not installed.startswith(prefix): + raise RuntimeError(f"{dist_name} expected {prefix}, got {installed}") + print(f"PASS import {module_name} version={installed}") + +for module_name in ("torchada", "vllm", "vllm_musa"): + module = importlib.import_module(module_name) + print(f"PASS import {module_name} version={getattr(module, '__version__', 'unknown')}") +PY + +RUN rm -rf \ + /root/.cache/pip \ + /root/.cache/vllm-musa \ + /tmp/pip-* + +CMD ["/bin/bash"] diff --git a/docs/mdm-developer-guide.md b/docs/mdm-developer-guide.md index d297a77b803c..d8223c1964ee 100644 --- a/docs/mdm-developer-guide.md +++ b/docs/mdm-developer-guide.md @@ -43,10 +43,14 @@ is fine for running but not for `regen`. ## 1. Build & install -Prereqs: a MUSA environment (`torch_musa`, `torchada`, `mate`, … per -`pyproject.toml`). +Prereqs: a MUSA runtime/toolkit environment. Install the build, common, and +MUSA-private Python dependencies, including torch/torch_musa, from the +requirements entrypoints before installing `vllm-musa`. ```bash +# required before pip install . / pip install -e . +pip install -r requirements/build.txt -r requirements/musa.txt + # developer install (recommended) — vllm-musa editable: pip install -e . --no-build-isolation -v diff --git a/pyproject.toml b/pyproject.toml index 5993c62f76c3..9acd9453e7aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,4 +1,7 @@ [build-system] +# Keep build tool pins mirrored in requirements/build.txt. vllm-musa is +# installed with --no-build-isolation in MUSA images after MUSA-private runtime +# requirements such as torch/torch_musa have been installed. requires = ["setuptools>=80.10.2", "wheel"] build-backend = "setuptools.build_meta" @@ -25,18 +28,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] -dependencies = [ - "torch", - "torch_musa", - "torchada>=0.1.62", - "mate>=0.2.1", - "flash_attn_3>=0.1.4", - "mthreads-ml-py>=2.2.11", - "numpy<2.0", - "openai>=2.24.0", - "transformers==5.5.3", - "tilelang_musa>=0.1.8" -] +dynamic = ["dependencies"] [project.optional-dependencies] dev = [ diff --git a/requirements/build.txt b/requirements/build.txt new file mode 100644 index 000000000000..5459b55ead9f --- /dev/null +++ b/requirements/build.txt @@ -0,0 +1,16 @@ +# Build dependencies used by docker/musa.Dockerfile before +# pip install -e . --no-build-isolation -v. +# +# torch and torch_musa are hardware-private runtime dependencies. Keep their +# version pins in requirements/musa_private.txt, not in this build-only file. +cmake>=3.26.1 +ninja +packaging>=24.2 +setuptools>=80.10.2 +setuptools-scm>=8 +setuptools-rust>=1.9.0 +wheel +jinja2>=3.1.6 +regex +build +protobuf >= 5.29.6, !=6.30.*, !=6.31.*, !=6.32.*, !=6.33.0.*, !=6.33.1.*, !=6.33.2.*, !=6.33.3.*, !=6.33.4.* diff --git a/requirements/common.txt b/requirements/common.txt new file mode 100644 index 000000000000..f04b426c94a6 --- /dev/null +++ b/requirements/common.txt @@ -0,0 +1,5 @@ +# Runtime Python dependencies that are portable across MUSA images. +torchada>=0.1.62 +mthreads-ml-py>=2.2.11 +numpy==1.26 +openai>=2.24.0 diff --git a/requirements/musa.txt b/requirements/musa.txt new file mode 100644 index 000000000000..8506475d4b88 --- /dev/null +++ b/requirements/musa.txt @@ -0,0 +1,5 @@ +# Common dependencies +-r common.txt +-r musa_private.txt + +transformers==5.5.3 diff --git a/requirements/musa_private.txt b/requirements/musa_private.txt new file mode 100644 index 000000000000..c742a3c12fae --- /dev/null +++ b/requirements/musa_private.txt @@ -0,0 +1,15 @@ +# default PyPI source +# --extra-index-url https://pypi.org/simple + +# MUSA PyPI source +# Add the official MUSA Python package index here once it is published. + +torch==2.9.* +torch_musa==2.9.* +mate==0.2.3 +flash_attn_3==0.2.3 +flash_mla==0.2.3 +deep-gemm==0.2.3 +tilelang_musa==0.1.8 +apache-tvm-ffi==0.1.9.post2+musa.1 +torch_c_dlpack_ext==0.1.5 diff --git a/setup.py b/setup.py index d14a0bab746e..710973dc00bb 100644 --- a/setup.py +++ b/setup.py @@ -11,12 +11,6 @@ import torch - -def _ensure_numpy_compatible(): - """Ensure numpy<2 (MUSA/torch requirement); the vLLM install can pull numpy>=2.""" - subprocess.check_call([sys.executable, "-m", "pip", "install", "numpy<2", "-q"]) - - def _ensure_torchada_installed(): """Ensure torchada is installed (needed for torch.cuda patching).""" try: @@ -30,7 +24,6 @@ def _ensure_torchada_installed(): # Run dependency checks at setup start -_ensure_numpy_compatible() _ensure_torchada_installed() from setuptools import setup @@ -61,6 +54,32 @@ def _read_pins(): _PINS = _read_pins() + +def _read_requirements(filename, seen=None): + """Read pip requirements files with local -r includes.""" + requirements_dir = root / "requirements" + path = requirements_dir / filename + seen = set() if seen is None else seen + if path in seen: + return [] + seen.add(path) + + requirements = [] + for raw_line in path.read_text().splitlines(): + line = raw_line.strip() + if not line or line.startswith("#"): + continue + if " #" in line: + line = line.split(" #", 1)[0].strip() + if line.startswith("--"): + continue + if line.startswith("-r "): + requirements.extend(_read_requirements(line.split(maxsplit=1)[1], seen)) + else: + requirements.append(line) + return requirements + + configure_compiler_cache(root) # Detect editable install (pip install -e .) or develop mode @@ -454,9 +473,6 @@ def run(self): self._install_vllm(_VLLM_REPO.source_dir) - # Re-ensure numpy<2 after vllm installation (vllm may pull in numpy>=2) - _ensure_numpy_compatible() - super().run() @@ -464,13 +480,10 @@ def run(self): ext_modules=EXT_MODULES, cmdclass={"build_ext": _CustomBuildExt.with_options(use_ninja=True)}, include_package_data=False, - # pinned here because --no-build-isolation skips pyproject.toml deps - install_requires=[ - "torchada>=0.1.62", - "mthreads-ml-py>=2.2.11", - "numpy<2", - "openai>=2.24.0", - ], + # Runtime dependencies live in requirements/musa.txt so Docker and package + # metadata share one source. MUSA-private pins, including torch/torch_musa, + # are kept in requirements/musa_private.txt. + install_requires=_read_requirements("musa.txt"), ) # place the built vllm.* extensions into the editable vLLM clone (see the function).