Skip to content

Commit cc27fa3

Browse files
feat: streamline CUDA runtime dependency generation
Collapse runtime dependencies into the generated CUDA extras and update the generator, installer docs, and development workflow around the new CUDA-aware dependency model. Signed-off-by: Aaron Gonzales <aagonzales@nvidia.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 37cedcc commit cc27fa3

21 files changed

Lines changed: 1078 additions & 402 deletions

.claude/commands/bootstrap.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Set up the development environment from scratch.
1414
```bash
1515
make bootstrap-nss cpu # CPU-only (macOS or Linux without GPU)
1616
make bootstrap-nss cuda # CUDA 12.8 (Linux with NVIDIA GPU)
17-
make bootstrap-nss engine # Engine dependencies only (no torch)
17+
make bootstrap-nss cu130 # CUDA 13.0 (Linux with NVIDIA GPU)
18+
make bootstrap-nss docs # Documentation dependencies only
1819
make bootstrap-nss dev # Minimal dev dependencies only
1920
```
2021

.cursor/rules/repo-navigation.mdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Cursor discovers skills directly from `.agents/skills/` -- no symlinks needed.
2727

2828
| File | Purpose |
2929
|------|---------|
30-
| `pyproject.toml` | Package metadata, dependencies, extras (cpu/cu128/engine), uv config |
30+
| `pyproject.toml` | Package metadata, dependencies, runtime extras (cpu/cu128/cu130), uv config |
3131
| `pytest.ini` | Test markers, pytest options, timeout, parallelism |
3232
| `ruff.toml` | Ruff linting and formatting rules |
3333
| `mkdocs.yml` | Documentation site config (MkDocs Material) |

.cursor/setup-worktree.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ fi
1616

1717
# Bare --frozen installs the base environment. For GPU dev work (ty, import
1818
# checks, GPU tests) run the full command manually after setup:
19-
# uv sync --frozen --extra cu128 --extra engine --group dev
19+
# uv sync --frozen --extra cu128 --group dev
2020
uv sync --frozen
2121
echo "Venv ready: $(pwd)/.venv"
22-
echo "Note: for GPU extras run: uv sync --frozen --extra cu128 --extra engine --group dev"
22+
echo "Note: for GPU extras run: uv sync --frozen --extra cu128 --group dev"
2323

2424
for _envfile in .env .env.local mise.local.toml .local.envrc; do
2525
if [ -f "$ROOT_WORKTREE_PATH/$_envfile" ]; then

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Common commands: `make test` (unit tests), `make format` (auto-fix formatting +
2424
The canonical `uv sync` command for a full GPU/dev environment is:
2525

2626
```bash
27-
uv sync --frozen --extra cu128 --extra engine --group dev
27+
uv sync --frozen --extra cu128 --group dev
2828
```
2929

3030
Bare `uv sync --frozen` (without extras) installs an incomplete environment -- `ty`, import checks, and GPU tests will fail.

CONTRIBUTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
6060
# Install Python dependencies (choose one)
6161
make bootstrap-nss cpu # CPU-only (macOS or Linux without GPU)
6262
make bootstrap-nss cuda # CUDA 12.8 (Linux with NVIDIA GPU)
63-
make bootstrap-nss engine # Engine dependencies only
63+
make bootstrap-nss cu130 # CUDA 13.0 (Linux with NVIDIA GPU)
64+
make bootstrap-nss docs # Documentation dependencies only
6465
make bootstrap-nss dev # Minimal dev dependencies only
6566
```
6667

Makefile

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,29 @@ verify-python-version: ## Verify Python version and install if necessary
8383

8484
.PHONY: bootstrap-python
8585
bootstrap-python: .venv ## Bootstrap Python dependencies. Set PYTORCH_DEPS to 'cpu' or 'cu128'. Here mostly for legacy usage.
86-
uv sync --frozen --extra ${PYTORCH_DEPS} --extra engine --group dev
86+
uv sync --frozen --extra ${PYTORCH_DEPS} --group dev
8787

8888
# Dynamic targets for bootstrap-nss
89-
# Usage: make bootstrap-nss {dev,engine,cpu,cuda}
90-
BOOTSTRAP_EXTRAS := dev engine cpu cuda cu128
89+
# Usage: make bootstrap-nss {dev,docs,cpu,cuda,cu128,cu130}
90+
BOOTSTRAP_EXTRAS := dev docs cpu cuda cu128 cu130
9191
$(BOOTSTRAP_EXTRAS):
9292
@:
9393

9494
.PHONY: bootstrap-nss
95-
bootstrap-nss: .venv ## Bootstrap Python dependencies. Usage: make bootstrap-nss {dev,engine,cpu,cuda}
95+
bootstrap-nss: .venv ## Bootstrap Python dependencies. Usage: make bootstrap-nss {dev,docs,cpu,cuda,cu128,cu130}
9696
$(eval EXTRA := $(filter-out $@, $(MAKECMDGOALS)))
9797
@echo "~~~~~~"
9898
@echo "attempting to install nss package with primary extra: $(EXTRA)"
9999
@if [ "$(EXTRA)" = "cuda" ]; then \
100-
uv sync --frozen --extra cu128 --extra engine --group dev; \
100+
uv sync --frozen --extra cu128 --group dev; \
101101
elif [ "$(EXTRA)" = "cu128" ]; then \
102-
uv sync --frozen --extra cu128 --extra engine --group dev; \
102+
uv sync --frozen --extra cu128 --group dev; \
103103
elif [ "$(EXTRA)" = "cpu" ]; then \
104-
uv sync --frozen --extra cpu --extra engine --group dev; \
105-
elif [ "$(EXTRA)" = "engine" ]; then \
106-
uv sync --frozen --extra engine --group dev; \
104+
uv sync --frozen --extra cpu --group dev; \
105+
elif [ "$(EXTRA)" = "cu130" ]; then \
106+
uv sync --frozen --extra cu130 --group dev; \
107+
elif [ "$(EXTRA)" = "docs" ]; then \
108+
uv sync --frozen --group docs; \
107109
elif [ "$(EXTRA)" = "dev" ]; then \
108110
uv sync --frozen --group dev; \
109111
else \

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,23 @@ Raw commands:
3636
CONSTRAINTS_URL="https://raw.githubusercontent.com/NVIDIA-NeMo/Safe-Synthesizer/main/constraints.txt"
3737

3838
# CUDA 12.8 with uv (recommended):
39-
uv pip install "nemo-safe-synthesizer[cu128,engine]" \
39+
uv pip install "nemo-safe-synthesizer[cu128]" \
4040
-c "$CONSTRAINTS_URL" \
4141
--index https://flashinfer.ai/whl/cu128 \
4242
--index https://download.pytorch.org/whl/cu128 \
4343
--index https://pypi.nvidia.com \
4444
--index-strategy unsafe-best-match
4545

4646
# CUDA 13.0 with uv (requires NVIDIA Linux driver 580.65.06+):
47-
uv pip install "nemo-safe-synthesizer[cu130,engine]" \
47+
uv pip install "nemo-safe-synthesizer[cu130]" \
4848
-c "$CONSTRAINTS_URL" \
4949
--index https://flashinfer.ai/whl/cu130 \
5050
--index https://download.pytorch.org/whl/cu130 \
5151
--index https://pypi.nvidia.com \
5252
--index-strategy unsafe-best-match
5353

5454
# CUDA 12.8 with pip:
55-
pip install "nemo-safe-synthesizer[cu128,engine]" \
55+
pip install "nemo-safe-synthesizer[cu128]" \
5656
-c "$CONSTRAINTS_URL" \
5757
--extra-index-url https://download.pytorch.org/whl/cu128 \
5858
--extra-index-url https://flashinfer.ai/whl/cu128 \
@@ -65,9 +65,9 @@ Or install from source:
6565
git clone https://github.com/NVIDIA-NeMo/Safe-Synthesizer.git
6666
cd Safe-Synthesizer
6767
make setup # installs the pinned mise version (if missing) + pinned tool versions from mise.lock
68-
uv sync --frozen --extra cu128 --extra engine --group dev
68+
uv sync --frozen --extra cu128 --group dev
6969
# or, for CUDA 13.0:
70-
uv sync --frozen --extra cu130 --extra engine --group dev
70+
uv sync --frozen --extra cu130 --group dev
7171
```
7272

7373
Development tools (`ruff`, `ty`, `yq`, `gh`, etc.) are managed via [mise](https://mise.jdx.dev/). Tool versions are declared in `.mise.toml` and locked in `mise.lock` (committed). mise also manages environment variables -- place project-local secrets or overrides in `.env` or `.env.local` (both git-ignored, auto-loaded by mise).

containers/Dockerfile.cuda

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#
66
# Stages:
77
# tools -- install mise and all dev tools (uv, ruff, etc.)
8-
# deps -- install Python, uv, and all cu128+engine dependencies
8+
# deps -- install Python, uv, and all cu128 dependencies
99
# runtime -- minimal CLI wrapper (ENTRYPOINT entrypoint.sh -> safe-synthesizer)
1010
# dev -- extends runtime with dev tools, tests, and interactive shell
1111
#
@@ -142,14 +142,14 @@ RUN --mount=type=cache,target=/root/.cache/uv \
142142
# not when source code changes.
143143
COPY pyproject.toml uv.lock ./
144144
RUN --mount=type=cache,target=/root/.cache/uv \
145-
uv sync --no-install-project --extra cu128 --extra engine --no-group dev
145+
uv sync --no-install-project --extra cu128 --no-group dev
146146

147147
# -- Project layer: install the project (non-editable so the venv is
148148
# self-contained and source code is not needed in the runtime image).
149149
COPY README.md ./
150150
COPY src/ src/
151151
RUN --mount=type=cache,target=/root/.cache/uv \
152-
uv sync --no-editable --extra cu128 --extra engine --no-group dev
152+
uv sync --no-editable --extra cu128 --no-group dev
153153

154154
# ---------------------------------------------------------------------------
155155
# Stage 3: runtime -- minimal image wrapping the safe-synthesizer CLI
@@ -233,7 +233,7 @@ COPY . .
233233

234234
# Install dev dependencies into the existing venv.
235235
RUN --mount=type=cache,target=/root/.cache/uv \
236-
uv sync --extra cu128 --extra engine --group dev
236+
uv sync --extra cu128 --group dev
237237

238238
RUN git config --global --add safe.directory /workspace
239239

cuda_deps.toml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
base_dependencies = [
4+
requires_torch = [
55
"accelerate",
66
"bitsandbytes==0.49.1",
77
{ name = "flashinfer-python", version = "0.6.6", sys_platform = "linux", source_kind = "flashinfer", source_marker = "sys_platform=='linux'" },
@@ -17,6 +17,37 @@ base_dependencies = [
1717
"vllm==0.18.0; sys_platform == 'linux'",
1818
]
1919

20+
runtime_deps = [
21+
"anyascii",
22+
"pycountry",
23+
"betterproto",
24+
"flashtext",
25+
"cached-property",
26+
"category-encoders",
27+
"dython",
28+
"dateparser",
29+
"faker",
30+
"datasets>=4.8.4",
31+
"huggingface-hub>=0.34.4,<1",
32+
"json-repair",
33+
"matplotlib",
34+
"outlines>=1.0.0",
35+
"prv-accountant",
36+
"smart-open==7.0.5",
37+
"python-stdnum",
38+
"pandas>=2.1.3, <3",
39+
"plotly",
40+
"ratelimit",
41+
"scikit-learn",
42+
"range_regex>=0.1.0",
43+
"tenacity==9.1.4",
44+
"tiktoken>=0.7.0,<1.0",
45+
"tldextract",
46+
"tqdm>=4.67.1",
47+
"urllib3>=2.6.1",
48+
"wandb==0.26.1",
49+
]
50+
2051
cuda_dependencies = [
2152
{ name = "flashinfer-jit-cache", version = "0.6.6", local = "{torch_local_version}", sys_platform = "linux", source_kind = "flashinfer", source_marker = "sys_platform=='linux'", variants = ["cu128"] },
2253
{ name = "nvidia-cublas", sys_platform = "linux" },
@@ -28,7 +59,7 @@ cuda_dependencies = [
2859
{ name = "xformers", version = "v0.0.34", sys_platform = "linux", arch = "x86_64", source_kind = "pytorch" },
2960
]
3061

31-
generated_extras = ["cpu", "cu128", "cu130"]
62+
generated_extras = ["engine", "cpu", "cu128", "cu130"]
3263

3364
# CUDA Python packaging context:
3465
# - Starting with CUDA Python 12.8, cuda-python is a metapackage that currently

docs/developer-guide/docker.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ flowchart TD
2424
2525
subgraph stages [Build Stages]
2626
tools["tools\nInstalls mise + all dev tools\n(.mise.toml is single source of truth)"]
27-
deps["deps\nInstalls Python 3.11 via uv\nuv sync cu128+engine"]
27+
deps["deps\nInstalls Python 3.11 via uv\nuv sync cu128"]
2828
runtime["runtime\nCopies venv + Python\nNon-root appuser\ntini + entrypoint.sh"]
2929
dev["dev\nExtends runtime\nCopies mise tree from tools\nRoot user"]
3030
end
@@ -44,7 +44,7 @@ flowchart TD
4444
Uses the [mise Docker cookbook](https://mise.jdx.dev/mise-cookbook/docker.html)
4545
pattern with `MISE_DATA_DIR=/mise` for stable, copyable paths.
4646
- deps: copies the uv binary from `tools`, then installs Python and all
47-
cu128+engine dependencies. Uses `--mount=type=cache` to avoid
47+
cu128 dependencies. Uses `--mount=type=cache` to avoid
4848
re-downloading ~10 GB of PyTorch/CUDA wheels.
4949
- runtime: copies the venv and uv-managed Python into a fresh CUDA runtime
5050
base. Runs as non-root `appuser` (uid 1000). GPU access is declared via
@@ -263,7 +263,7 @@ To reduce size:
263263
| Aspect | `Dockerfile.cuda` | `Dockerfile.test_ci` |
264264
|--------|-------------------|----------------------|
265265
| Base | `nvidia/cuda:12.8.1-runtime-ubuntu22.04` | `python:3.11-slim` |
266-
| Extras | `cu128` + `engine` | `cpu` + `engine` |
266+
| Extras | `cu128` | `cpu` |
267267
| GPU | Required | Not needed |
268268
| Stages | `tools` / `deps` / `runtime` / `dev` | `setup` / `install-deps` |
269269
| Use case | Training, generation, evaluation | CPU-only unit tests and CI checks |

0 commit comments

Comments
 (0)