Files
nvidia-nemo--speech/docker/Dockerfile
T
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:28:58 +08:00

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