ba4be087d5
Create PR to main with cherry-pick from release / cherry-pick (push) Waiting to run
CICD NeMo / pre-flight (push) Waiting to run
CICD NeMo / configure (push) Blocked by required conditions
CICD NeMo / cicd-main-unit-tests (push) Blocked by required conditions
CICD NeMo / cicd-main-speech (push) Blocked by required conditions
CICD NeMo / code-linting (push) Blocked by required conditions
CICD NeMo / cicd-wait-in-queue (push) Blocked by required conditions
CICD NeMo / cicd-test-container-build (push) Blocked by required conditions
CICD NeMo / cicd-import-tests (push) Blocked by required conditions
CICD NeMo / L0_Setup_Test_Data_And_Models (push) Blocked by required conditions
CICD NeMo / Nemo_CICD_Test (push) Blocked by required conditions
CICD NeMo / Coverage (e2e) (push) Blocked by required conditions
CICD NeMo / Coverage (unit-test) (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Build, validate, and release Neural Modules / pre-flight (push) Waiting to run
Build, validate, and release Neural Modules / release (push) Blocked by required conditions
Build, validate, and release Neural Modules / release-summary (push) Blocked by required conditions
295 lines
9.6 KiB
Docker
295 lines
9.6 KiB
Docker
# syntax=docker/dockerfile:1-labs
|
|
|
|
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# This CI Dockerfile supports CUDA 13 and CUDA 12 from a single BASE_IMAGE
|
|
# build arg. The default is the recommended CUDA 13 image:
|
|
# nvcr.io/nvidia/cuda-dl-base:26.04-cuda13.2-devel-ubuntu24.04
|
|
# The current recommended CUDA 12 image is:
|
|
# nvcr.io/nvidia/cuda-dl-base:25.06-cuda12.9-devel-ubuntu24.04
|
|
#
|
|
# The build derives CUDA_FLAVOR internally from BASE_IMAGE by matching
|
|
# "cuda13" or "cuda12" in the image tag. That flavor selects the matching uv
|
|
# extra (cu13 or cu12) and CUDA Python package include path. If BASE_IMAGE does
|
|
# not contain either token, the build fails early.
|
|
#
|
|
# Example CUDA 13 H100+ build:
|
|
# docker buildx build -f docker/Dockerfile \
|
|
# --build-arg GPU_TARGET=h100plus .
|
|
# Example CUDA 12 A100 build:
|
|
# docker buildx build -f docker/Dockerfile \
|
|
# --build-arg BASE_IMAGE=nvcr.io/nvidia/cuda-dl-base:25.06-cuda12.9-devel-ubuntu24.04 \
|
|
# --build-arg GPU_TARGET=a100 .
|
|
#
|
|
# GPU_TARGET controls compiled Automodel dependency tuning. "h100plus" builds
|
|
# for SM90/SM100/SM120 and includes H100+ features such as DeepEP and
|
|
# flash-attn-4. "a100" builds only SM80 and uses an A100-specific DeepEP patch
|
|
# to avoid unsupported newer-GPU/NVSHMEM build paths. This keeps CI images
|
|
# smaller and avoids compiling kernels for architectures a target image cannot
|
|
# use.
|
|
ARG BASE_IMAGE=nvcr.io/nvidia/cuda-dl-base:26.04-cuda13.2-devel-ubuntu24.04
|
|
FROM ${BASE_IMAGE} AS base-image
|
|
ARG BASE_IMAGE
|
|
ARG UV_VERSION=0.11.27
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
ENV TRANSFORMERS_OFFLINE=0
|
|
ENV HYDRA_FULL_ERROR=1
|
|
ENV PYTHONUNBUFFERED=1
|
|
ENV UV_PYTHON=3.13
|
|
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
|
|
ENV UV_LINK_MODE=copy
|
|
ENV UV_NO_CACHE=1
|
|
ENV UV_NO_PROGRESS=1
|
|
ENV VIRTUAL_ENV=/opt/venv
|
|
ENV PATH="/root/.local/bin:${VIRTUAL_ENV}/bin:${PATH}"
|
|
|
|
RUN <<"EOF" bash -ex
|
|
apt-get update
|
|
apt-get install -y \
|
|
curl \
|
|
git
|
|
apt-get clean
|
|
EOF
|
|
# NOTE: removed libsndfile1. Soundfile ships with its own version of libsndfile1
|
|
|
|
RUN <<"EOF" bash -ex
|
|
curl -LsSf "https://astral.sh/uv/${UV_VERSION}/install.sh" | sh
|
|
uv --version
|
|
EOF
|
|
|
|
RUN <<"EOF" bash -euxo pipefail
|
|
case "${BASE_IMAGE}" in
|
|
*cuda12*) cuda_flavor=cu12 ;;
|
|
*cuda13*) cuda_flavor=cu13 ;;
|
|
*)
|
|
echo "Cannot derive CUDA flavor from BASE_IMAGE='${BASE_IMAGE}'. Expected image tag containing 'cuda12' or 'cuda13'."
|
|
exit 1
|
|
;;
|
|
esac
|
|
cuda_major_minor="$(sed -n 's/.*cuda\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' <<<"${BASE_IMAGE}")"
|
|
if [[ -z "${cuda_major_minor}" ]]; then
|
|
echo "Cannot derive CUDA major.minor from BASE_IMAGE='${BASE_IMAGE}'. Expected image tag containing e.g. 'cuda12.9' or 'cuda13.2'."
|
|
exit 1
|
|
fi
|
|
cat >/usr/local/bin/nemo-cuda-flavor <<SCRIPT
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
echo "${cuda_flavor}"
|
|
SCRIPT
|
|
cat >/usr/local/bin/nemo-install-cuda-python <<SCRIPT
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
cuda_major_minor="${cuda_major_minor}"
|
|
cuda_major="\${cuda_major_minor%%.*}"
|
|
cuda_minor="\${cuda_major_minor#*.}"
|
|
cuda_next_minor="\$((cuda_minor + 1))"
|
|
uv pip install \
|
|
"cuda-bindings>=\${cuda_major_minor}.0,<\${cuda_major}.\${cuda_next_minor}" \
|
|
"cuda-python>=\${cuda_major_minor}.0,<\${cuda_major}.\${cuda_next_minor}"
|
|
SCRIPT
|
|
chmod +x /usr/local/bin/nemo-cuda-flavor /usr/local/bin/nemo-install-cuda-python
|
|
echo "Derived CUDA flavor: ${cuda_flavor}"
|
|
echo "Derived CUDA Python major.minor: ${cuda_major_minor}"
|
|
EOF
|
|
|
|
WORKDIR /workspace
|
|
COPY pyproject.toml uv.lock /workspace/
|
|
COPY nemo/__init__.py nemo/package_info.py /workspace/nemo/
|
|
RUN <<"EOF" bash -ex
|
|
cuda_flavor="$(nemo-cuda-flavor)"
|
|
uv sync --link-mode copy --locked --extra all --extra "${cuda_flavor}" --group test
|
|
nemo-install-cuda-python
|
|
EOF
|
|
|
|
RUN <<"EOF" bash -ex
|
|
# Container-only runtime utilities. Keep these out of pyproject.toml so they do
|
|
# not become NeMo package dependencies.
|
|
uv pip install \
|
|
dill \
|
|
orjson
|
|
|
|
case "$(nemo-cuda-flavor)" in
|
|
cu12) torchcodec_index=https://download.pytorch.org/whl/cu126 ;;
|
|
cu13) torchcodec_index=https://download.pytorch.org/whl/cu132 ;;
|
|
esac
|
|
uv pip install --index-url "${torchcodec_index}" torchcodec
|
|
EOF
|
|
|
|
FROM base-image AS automodel-deps
|
|
ARG GPU_TARGET=h100plus
|
|
ARG DEEPEP_REPO=https://github.com/deepseek-ai/DeepEP.git
|
|
ARG DEEPEP_REF=v1.2.1
|
|
ARG FLASH_ATTN_MAX_JOBS=8
|
|
ARG FLASH_ATTN_NVCC_THREADS=1
|
|
|
|
ENV PIP_NO_CACHE_DIR=1
|
|
|
|
COPY external/patches/deepep_v1_a100_disable_nvshmem.patch /tmp/patches/
|
|
RUN <<"EOF" bash -euxo pipefail
|
|
apt-get update
|
|
apt-get install -y \
|
|
build-essential \
|
|
ca-certificates \
|
|
cmake \
|
|
ninja-build \
|
|
patch
|
|
apt-get clean
|
|
rm -rf /var/lib/apt/lists/*
|
|
EOF
|
|
|
|
RUN <<"EOF" bash -euxo pipefail
|
|
cat >/usr/local/bin/automodel-build-env <<'SCRIPT'
|
|
case "${GPU_TARGET}" in
|
|
h100plus)
|
|
export DEEPEP_TORCH_CUDA_ARCH_LIST="9.0+PTX"
|
|
export TORCH_CUDA_ARCH_LIST="9.0;10.0;12.0"
|
|
export NVTE_CUDA_ARCHS="90;100;120"
|
|
export FLASH_ATTN_CUDA_ARCHS="90;100;120"
|
|
export CMAKE_CUDA_ARCHITECTURES="90;100;120"
|
|
;;
|
|
a100)
|
|
export DEEPEP_TORCH_CUDA_ARCH_LIST="8.0"
|
|
export TORCH_CUDA_ARCH_LIST="8.0"
|
|
export NVTE_CUDA_ARCHS="80"
|
|
export FLASH_ATTN_CUDA_ARCHS="80"
|
|
export CMAKE_CUDA_ARCHITECTURES="80"
|
|
export DISABLE_SM90_FEATURES=1
|
|
;;
|
|
*)
|
|
echo "Unsupported GPU_TARGET='${GPU_TARGET}'. Expected 'h100plus' or 'a100'."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
CUDA_FLAVOR="$(nemo-cuda-flavor)"
|
|
AUTOMODEL_CCCL_INCLUDES="/usr/local/cuda/include/cccl"
|
|
PYTHON_CCCL_INCLUDE="${VIRTUAL_ENV}/lib/python${UV_PYTHON}/site-packages/nvidia/${CUDA_FLAVOR}/include/cccl"
|
|
if [[ -d "${PYTHON_CCCL_INCLUDE}" ]]; then
|
|
AUTOMODEL_CCCL_INCLUDES="${AUTOMODEL_CCCL_INCLUDES}:${PYTHON_CCCL_INCLUDE}"
|
|
fi
|
|
export CPATH="${AUTOMODEL_CCCL_INCLUDES}${CPATH:+:${CPATH}}"
|
|
export CPLUS_INCLUDE_PATH="${AUTOMODEL_CCCL_INCLUDES}${CPLUS_INCLUDE_PATH:+:${CPLUS_INCLUDE_PATH}}"
|
|
export NVTE_FRAMEWORK=pytorch
|
|
export MAX_JOBS="${FLASH_ATTN_MAX_JOBS}"
|
|
export NVCC_THREADS="${FLASH_ATTN_NVCC_THREADS}"
|
|
SCRIPT
|
|
mkdir -p /opt/automodel-src
|
|
EOF
|
|
|
|
COPY external/patches/flash_attn_4_sm120_disable_tma_o.patch /tmp/patches/
|
|
RUN <<"EOF" bash -euxo pipefail
|
|
source /usr/local/bin/automodel-build-env
|
|
uv pip install --upgrade \
|
|
cmake \
|
|
ninja \
|
|
nvidia-mathdx \
|
|
packaging \
|
|
pip \
|
|
psutil \
|
|
pybind11 \
|
|
setuptools \
|
|
setuptools-scm \
|
|
wheel
|
|
|
|
automodel_extra=compiled
|
|
if [[ "${GPU_TARGET}" == "h100plus" ]]; then
|
|
automodel_extra=compiled
|
|
elif [[ "${GPU_TARGET}" == "a100" ]]; then
|
|
automodel_extra=compiled-a100
|
|
fi
|
|
cuda_flavor="$(nemo-cuda-flavor)"
|
|
uv sync \
|
|
--inexact \
|
|
--link-mode copy \
|
|
--locked \
|
|
--extra all \
|
|
--extra "${cuda_flavor}" \
|
|
--extra "${automodel_extra}" \
|
|
--group test
|
|
nemo-install-cuda-python
|
|
|
|
if [[ "${GPU_TARGET}" == "a100" ]]; then
|
|
git clone "${DEEPEP_REPO}" /opt/automodel-src/DeepEP
|
|
git -C /opt/automodel-src/DeepEP checkout -f "${DEEPEP_REF}"
|
|
patch -d /opt/automodel-src/DeepEP -p1 < /tmp/patches/deepep_v1_a100_disable_nvshmem.patch
|
|
TORCH_CUDA_ARCH_LIST="${DEEPEP_TORCH_CUDA_ARCH_LIST}" \
|
|
uv pip install \
|
|
--no-build-isolation \
|
|
--no-deps \
|
|
/opt/automodel-src/DeepEP
|
|
fi
|
|
|
|
if [[ "${GPU_TARGET}" == "h100plus" ]]; then
|
|
# flash-attn-4 requires apache-tvm-ffi 0.1.11, while mamba-ssm
|
|
# currently constrains the solved environment to apache-tvm-ffi<=0.1.9.
|
|
cutlass_packages=(
|
|
"nvidia-cutlass-dsl==4.5.2"
|
|
"nvidia-cutlass-dsl-libs-base==4.5.2"
|
|
)
|
|
if [[ "$(nemo-cuda-flavor)" == "cu13" ]]; then
|
|
cutlass_packages+=("nvidia-cutlass-dsl-libs-cu13==4.5.2")
|
|
fi
|
|
uv pip install \
|
|
--no-deps \
|
|
"apache-tvm-ffi==0.1.11" \
|
|
"${cutlass_packages[@]}" \
|
|
"quack-kernels==0.5.0" \
|
|
"torch-c-dlpack-ext==0.1.5"
|
|
|
|
mkdir -p /opt/automodel-src/flash-attn-4 /tmp/flash-attn-4
|
|
python -m pip download \
|
|
--no-binary=flash-attn-4 \
|
|
--no-deps \
|
|
--dest /tmp/flash-attn-4 \
|
|
"flash-attn-4==4.0.0b15"
|
|
tar -xf /tmp/flash-attn-4/flash_attn_4-*.tar.gz -C /opt/automodel-src/flash-attn-4 --strip-components=1
|
|
patch -d /opt/automodel-src/flash-attn-4 -p1 < /tmp/patches/flash_attn_4_sm120_disable_tma_o.patch
|
|
|
|
MAX_JOBS="${FLASH_ATTN_MAX_JOBS}" \
|
|
NVCC_THREADS="${FLASH_ATTN_NVCC_THREADS}" \
|
|
uv pip install \
|
|
--no-build-isolation \
|
|
--no-deps \
|
|
/opt/automodel-src/flash-attn-4
|
|
fi
|
|
EOF
|
|
|
|
FROM base-image
|
|
COPY --from=automodel-deps /opt/venv /opt/venv
|
|
|
|
ENV NVIDIA_BUILD_ID=${NVIDIA_BUILD_ID:-<unknown>}
|
|
LABEL com.nvidia.build.id="${NVIDIA_BUILD_ID}"
|
|
ARG NVIDIA_BUILD_REF
|
|
LABEL com.nvidia.build.ref="${NVIDIA_BUILD_REF}"
|
|
ARG RC_DATE=00.00
|
|
ARG TARGETARCH
|
|
|
|
ARG INSTALL_FFMPEG=false
|
|
RUN <<"EOF" bash -ex
|
|
if [ "${INSTALL_FFMPEG}" = "true" ]; then
|
|
apt-get update
|
|
apt-get install -y ffmpeg
|
|
apt-get clean
|
|
rm -rf /var/lib/apt/lists/*
|
|
fi
|
|
EOF
|
|
|
|
COPY nemo /workspace/nemo
|
|
|
|
# NOTICES.txt file points to where the OSS source code is archived
|
|
RUN echo "This distribution includes open source which is archived at the following URL: https://opensource.nvidia.com/oss/teams/nvidia/nemo/${RC_DATE}:linux-${TARGETARCH}/index.html" > NOTICES.txt && \
|
|
echo "For further inquiries or assistance, contact us at oss-requests@nvidia.com" >> NOTICES.txt
|