Skip to content

Commit 6f08731

Browse files
cjluo-nvclaude
andauthored
docs(eval skill): vLLM backend env vars + SLURM HF-cache/cpu_partition guidance (#1625)
### What does this PR do? Type of change: documentation Hardens the **evaluation** skill with operational guidance discovered while running AA-Index evals (NVFP4 Nemotron-3-Nano) on SLURM. Two themes: **1. vLLM backend env vars (original commits).** Some models need a model-card backend toggle that is an env var, not a CLI flag — e.g. NVFP4 MoE models like [NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4) need `VLLM_USE_FLASHINFER_MOE_FP4=1` + `VLLM_FLASHINFER_MOE_BACKEND=throughput`. These go in `deployment.env_vars` (with the `lit:` prefix), not the `vllm serve` command. **2. SLURM deploy/eval operational lessons (new commits).** - **`mount_home: false` always.** Some internal cluster templates default it `true`, which mounts the host `~/.cache`; where that is a symlink into a shared/networked filesystem, it dangles in the container and the vLLM `trust-remote-code` deploy dies with `FileNotFoundError: /root/.cache/huggingface` — **invisible to `--dry-run`**. - **HF cache:** mount the realpath of `~/.cache/huggingface` to `/hf-cache` and set `HF_HOME: lit:/hf-cache` for both stages. - **`execution.cpu_partition`:** on split GPU/CPU-partition clusters, the CPU-only MLflow auto-export job is rejected by the GPU partition and marks the whole task FAILED despite `EVAL_EXIT_CODE=0`. Set `cpu_partition` to route it correctly. - **Top-level `env_vars:`** for vars both stages need (`HF_TOKEN`, `HF_HOME`); `execution.env_vars` is unsupported and hard-errors. - **`lcr.md`:** `LOG_LEVEL=WARNING` to skip logging AA-LCR's ~120K-token inputs. ### Usage ```yaml execution: cpu_partition: <cpu-partition> # CPU-only auto-export job mounts: mount_home: false deployment: { <shared-fs>/<user>/.cache/huggingface: /hf-cache } evaluation: { <shared-fs>/<user>/.cache/huggingface: /hf-cache } env_vars: # shared by both stages HF_TOKEN: host:HF_TOKEN HF_HOME: lit:/hf-cache deployment: env_vars: VLLM_USE_FLASHINFER_MOE_FP4: lit:1 VLLM_FLASHINFER_MOE_BACKEND: lit:throughput ``` ### Testing Docs/skill-only. Validated end-to-end by running the full AA suite (GPQA + SciCode + AA-LCR) across 5 NVFP4 checkpoints on SLURM: dry-run + canary + full runs all SUCCESS with these settings. Pre-commit (yamlfmt, markdownlint) passed. ### Before your PR is "*Ready for review*" - Is this change backward compatible?: ✅ - If you copied code from any other sources or added a new PIP dependency, did you follow guidance in `CONTRIBUTING.md`: N/A - Did you write any new necessary tests?: N/A - Did you update Changelog?: N/A - Did you get Claude approval on this PR?: ❌ 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified where backend-related environment variables must be configured (deployment-level) and not embedded in execution commands. * Added guidance to mount the real HuggingFace cache path and set home-mounting to false for containerized SLURM runs. * Documented routing CPU-only jobs via CPU partitions and added a task-level LOG_LEVEL setting to reduce verbose long-context logging. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Chenjie Luo <chenjiel@nvidia.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent bdb793a commit 6f08731

4 files changed

Lines changed: 57 additions & 3 deletions

File tree

.agents/skills/evaluation/SKILL.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ nel skills build-config --execution <...> --deployment <...> --model_type <...>
8484
- **vLLM:** no `--quantization` flag by default — vLLM auto-detects from `quantization_config` / `hf_quant_config.json`. Add only when the card, vLLM version, or dry-run error requires it.
8585
- **SGLang:** may need `--quantization modelopt_fp8` / `modelopt_fp4` / `modelopt` — verify against installed version.
8686

87-
Some models need extra env vars (e.g. `VLLM_NVFP4_GEMM_BACKEND=marlin` for Nemotron Super) — discovered via model card research.
87+
Some models need extra vLLM backend env vars (model-card research) — e.g. `VLLM_NVFP4_GEMM_BACKEND=marlin` (Nemotron Super), or `VLLM_USE_FLASHINFER_MOE_FP4=1` + `VLLM_FLASHINFER_MOE_BACKEND=throughput` (NVFP4 MoE, e.g. NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4). Put them in `deployment.env_vars` (**not** `command`) with the `lit:` prefix (`VLLM_USE_FLASHINFER_MOE_FP4: lit:1`); see `example_eval.yaml` and Step 5's prefix rule.
8888

8989
**Auto-detect from `config.json`:**
9090

@@ -223,6 +223,8 @@ for f in "$PKG"/configs/execution/internal/slurm/*.yaml; do \
223223

224224
Hostname match → set `defaults: - execution: internal/slurm/<cluster>`, drop the redundant `execution.hostname` (keep account/output_dir/walltime), verify with `--dry-run`. Else keep `slurm/default` and fill hostname/account/output_dir manually.
225225

226+
On SLURM, several deploy/eval failures are invisible to `--dry-run` and only surface at canary (`mount_home`, HF cache, `cpu_partition`, top-level vs per-stage `env_vars`) — read `references/slurm.md`.
227+
226228
- Find every `???` left. Ask the user only for what can't be inferred (SLURM hostname/account/output_dir, MLflow tracking URI, etc.). Don't propose defaults; let them give plain text.
227229
- **`parallelism`** — size it yourself from the run shape (total requests = `dataset_size × repeats` vs GPU serving capacity), and set `--max-num-seqs` to match. Read `references/parallelism.md` for the decision rule and worked examples; only ask the user if a non-GPU cap (e.g. judge rate limit) is unknown.
228230
- Ask about other defaults they may want to change (partition, walltime, MLflow tags).
@@ -295,12 +297,12 @@ Default images:
295297
| Framework | Image | Registry |
296298
| --- | --- | --- |
297299
| vLLM | `vllm/vllm-openai:v0.19.1` (bump per recipe; never `:latest`) | DockerHub |
298-
| vLLM (NVFP4 on Blackwell) | `vllm/vllm-openai:v0.19.1-cu130` (bump to `cu130-nightly-<arch>` for new archs) | DockerHub |
300+
| vLLM (NVFP4 on B300/GB300) | `vllm/vllm-openai:v0.19.1-cu130` (bump to `cu130-nightly-<arch>` for new archs) | DockerHub |
299301
| SGLang | `lmsysorg/sglang:latest` | DockerHub |
300302
| TRT-LLM | `nvcr.io/nvidia/tensorrt-llm/release:...` | NGC |
301303
| Eval tasks | `nvcr.io/nvidia/eval-factory/*:26.03` | NGC |
302304

303-
> NVFP4 checkpoints on Blackwell (sm_100/sm_103) need the `cu130-nightly` image — cu129/v0.19.1 lack sm_103 FP4 kernels (see the "NVFP4 on Blackwell" note in Step 3).
305+
> NVFP4 checkpoints on B300/GB300 (sm_103) need the `cu130` image — cu129/v0.19.1 lack sm_103 FP4 kernels (see the "NVFP4 on Blackwell" note in Step 3).
304306

305307
Public images → submit without preflight. Private/restricted → check credentials:
306308

.agents/skills/evaluation/recipes/examples/example_eval.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,24 @@ execution:
5656
# On the slurm/default fallback it's gpu:8 — set to the node's GPU count or sbatch
5757
# fails "Requested node configuration is not available" (4-GPU GB300 -> gpu:4).
5858
mounts:
59+
# mount_home ALWAYS false: true mounts host ~/.cache, which (if a shared-fs symlink) dangles
60+
# in-container -> vLLM deploy dies "FileNotFoundError /root/.cache/huggingface" (unseen by
61+
# --dry-run). Instead mount the real HF cache to /hf-cache + set HF_HOME below. See SKILL Step 4.
5962
mount_home: false
63+
# deployment: { <shared-fs>/<user>/.cache/huggingface: /hf-cache }
64+
# evaluation: { <shared-fs>/<user>/.cache/huggingface: /hf-cache }
6065
auto_export: # REQUIRED trigger for auto-export. Without this, the
6166
destinations: # export.mlflow block below is ignored and the run is
6267
- mlflow # NOT uploaded — you'd have to `nel export` it by hand.
6368
deployment:
6469
env_vars:
6570
HF_TOKEN: host:HF_TOKEN
71+
HF_HOME: lit:/hf-cache # with the /hf-cache mount above
72+
# vLLM backend env vars go HERE, not in the command below. Some models need
73+
# a card-documented toggle — e.g. NVFP4 MoE (NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4)
74+
# needs FlashInfer FP4 kernels. Uncomment per card (`lit:` prefix, Step 5):
75+
# VLLM_USE_FLASHINFER_MOE_FP4: lit:1
76+
# VLLM_FLASHINFER_MOE_BACKEND: lit:throughput
6677
checkpoint_path: ???
6778
hf_model_handle:
6879
served_model_name: ???
@@ -96,6 +107,7 @@ deployment:
96107
evaluation:
97108
env_vars:
98109
HF_TOKEN: host:HF_TOKEN
110+
HF_HOME: lit:/hf-cache # with the /hf-cache mount above
99111
# nemo-skills tasks (ns_*) hard-require the served-endpoint api key env var
100112
# (api_key_name below) to be set WITH A VALUE inside the eval container.
101113
# A shell `export DUMMY_API_KEY=dummy` does NOT reach the SLURM container —

.agents/skills/evaluation/recipes/tasks/aa/lcr.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ block. Per SKILL.md Step 3, the deployment flag must live inside
4242
container: nvcr.io/nvidia/eval-factory/nemo-skills:26.03
4343
env_vars:
4444
INFERENCE_API_KEY: host:INFERENCE_API_KEY
45+
LOG_LEVEL: lit:WARNING # Skip logging the long context inputs.
4546
nemo_evaluator_config:
4647
target:
4748
api_endpoint:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SLURM gotchas (invisible to `--dry-run`; surface at canary)
2+
3+
Use this reference when filling `execution` for a SLURM run (Step 4). These
4+
deploy/eval failures pass `--dry-run` clean and only show up once a real job is
5+
scheduled (canary), so resolve them up front.
6+
7+
## `mount_home: false`
8+
9+
`mount_home: true` mounts the host `~/.cache` into the container. A shared-fs
10+
symlink there (common for `~/.cache/huggingface`) dangles in-container → deploy
11+
dies with `FileNotFoundError /root/.cache/huggingface`. Mount the real cache to
12+
`/hf-cache` and point `HF_HOME` at it instead (see the snippet below).
13+
14+
## `cpu_partition: <cpu-partition>`
15+
16+
**Required for MLflow `auto_export` to work** on clusters with separate GPU/CPU
17+
partitions. If not specified, NEL runs the export (a CPU-only job) on the GPU
18+
partition — it does not auto-route — which gets rejected
19+
(`Cannot find GPU specification`) and fails the task despite `EVAL_EXIT_CODE=0`.
20+
Set it to the CPU partition (e.g. `cpu`).
21+
22+
## Shared vs stage-specific env vars
23+
24+
Shared env vars can go top-level `env_vars:` (merges into both the deployment and
25+
evaluation stages) or per-stage as the example shows; `execution.env_vars`
26+
hard-errors. Stage-specific vars stay under `deployment.env_vars` /
27+
`evaluation.env_vars`.
28+
29+
## Snippet
30+
31+
```yaml
32+
execution:
33+
cpu_partition: <cpu-partition>
34+
mounts:
35+
mount_home: false
36+
deployment: { <realpath ~/.cache/huggingface>: /hf-cache } # ssh <host> realpath ~/.cache/huggingface
37+
evaluation: { <realpath ~/.cache/huggingface>: /hf-cache }
38+
env_vars: { HF_TOKEN: host:HF_TOKEN, HF_HOME: lit:/hf-cache } # both stages
39+
```

0 commit comments

Comments
 (0)