|
| 1 | +# Nano3 QAOPD with TransferQueue |
| 2 | + |
| 3 | +This experimental example trains an NVFP4 Nemotron 3 Nano student against the |
| 4 | +matching BF16 teacher. Student generation produces NeMo-Gym trajectories, the |
| 5 | +teacher writes top-k logits directly to TransferQueue, and the Megatron policy |
| 6 | +worker consumes the queued fields during training. |
| 7 | + |
| 8 | +The supplied recipe preserves the development topology: |
| 9 | + |
| 10 | +- 8 nodes with 4 GPUs per node |
| 11 | +- Megatron TP=4, CP=4, EP=8 |
| 12 | +- vLLM TP=4 and EP=4 |
| 13 | +- 128 prompts with 4 generations per prompt |
| 14 | +- global training batch size 512 |
| 15 | +- teacher top-k 300, BF16 logits, and int32 indices |
| 16 | +- `mooncake_cpu` storage with microbatch-streamed top-k writeback |
| 17 | + |
| 18 | +Treat these as starting values. Memory capacity and parallelism must be checked |
| 19 | +again when the GPU type, sequence length, or batch shape changes. |
| 20 | + |
| 21 | +## Build an Enroot image |
| 22 | + |
| 23 | +Enroot imports OCI/Docker images; it does not build a Dockerfile itself. Build |
| 24 | +the NeMo RL release image first, then convert it to a squashfs image. |
| 25 | + |
| 26 | +Initialize the repository and build on the same CPU architecture as the target |
| 27 | +GPU cluster whenever possible: |
| 28 | + |
| 29 | +```bash |
| 30 | +git submodule update --init --recursive |
| 31 | + |
| 32 | +docker buildx build \ |
| 33 | + --platform linux/arm64 \ |
| 34 | + --target release \ |
| 35 | + --build-context nemo-rl=. \ |
| 36 | + --file docker/Dockerfile \ |
| 37 | + --tag nemo-rl:nano3-tq \ |
| 38 | + --load \ |
| 39 | + . |
| 40 | + |
| 41 | +enroot import \ |
| 42 | + --output nemo-rl-nano3-tq.sqsh \ |
| 43 | + dockerd://nemo-rl:nano3-tq |
| 44 | +``` |
| 45 | + |
| 46 | +Use `linux/amd64` for an x86_64 target. Cross-architecture builds require a |
| 47 | +Buildx builder with binfmt/QEMU support and are slower and less reliable for |
| 48 | +CUDA extension builds. A native build on the target architecture is preferred. |
| 49 | + |
| 50 | +If Docker and Enroot are on different machines, push to a registry and import |
| 51 | +the image there. The `#` separates the registry from the image path in Enroot's |
| 52 | +Docker URI syntax: |
| 53 | + |
| 54 | +```bash |
| 55 | +docker buildx build \ |
| 56 | + --platform linux/arm64 \ |
| 57 | + --target release \ |
| 58 | + --build-context nemo-rl=. \ |
| 59 | + --file docker/Dockerfile \ |
| 60 | + --tag registry.example.com/team/nemo-rl:nano3-tq \ |
| 61 | + --push \ |
| 62 | + . |
| 63 | + |
| 64 | +enroot import \ |
| 65 | + --arch arm64 \ |
| 66 | + --output nemo-rl-nano3-tq.sqsh \ |
| 67 | + docker://registry.example.com#team/nemo-rl:nano3-tq |
| 68 | +``` |
| 69 | + |
| 70 | +The resulting `.sqsh` file can be passed directly to Pyxis through |
| 71 | +`--container-image` or the repository's `ray.sub` launcher. |
| 72 | + |
| 73 | +Do not put registry credentials, Hugging Face tokens, W&B keys, or other |
| 74 | +secrets in the image, scripts, Git configuration, or recipe. Authenticate with |
| 75 | +the registry before import and inject runtime credentials through your |
| 76 | +cluster's secret-management mechanism. |
| 77 | + |
| 78 | +## Prepare data |
| 79 | + |
| 80 | +The launcher expects two files on storage shared by every Ray node: |
| 81 | + |
| 82 | +1. NeMo-Gym JSONL training data accepted by `NemoGymDataset`. |
| 83 | +2. JSONL calibration data used to initialize the NVFP4 quantizers. |
| 84 | + |
| 85 | +The model may be a shared local directory or the public Hugging Face model ID |
| 86 | +used by the recipe. For gated models, configure Hugging Face authentication in |
| 87 | +the runtime environment without adding credentials to this repository. |
| 88 | + |
| 89 | +## Run on an existing Ray cluster |
| 90 | + |
| 91 | +From the repository root inside the container: |
| 92 | + |
| 93 | +```bash |
| 94 | +bash examples/modelopt/nano3_qaopd_tq/run_training.sh \ |
| 95 | + /shared/data/train.jsonl \ |
| 96 | + /shared/data/quant-calibration.jsonl \ |
| 97 | + /shared/results/nano3-qaopd-tq \ |
| 98 | + nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 |
| 99 | +``` |
| 100 | + |
| 101 | +W&B is disabled in the example recipe. Checkpoints, JSON logs, and TensorBoard |
| 102 | +files are written below the supplied output directory. |
| 103 | + |
| 104 | +## Submit through Slurm, Pyxis, and Ray |
| 105 | + |
| 106 | +The submission wrapper takes all cluster-specific values as arguments. No |
| 107 | +account, partition, filesystem root, or credential is stored in the script. |
| 108 | + |
| 109 | +```bash |
| 110 | +bash examples/modelopt/nano3_qaopd_tq/submit_slurm.sh \ |
| 111 | + /shared/containers/nemo-rl-nano3-tq.sqsh \ |
| 112 | + SLURM_ACCOUNT \ |
| 113 | + SLURM_PARTITION \ |
| 114 | + /shared \ |
| 115 | + /shared/models/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16 \ |
| 116 | + /shared/data/train.jsonl \ |
| 117 | + /shared/data/quant-calibration.jsonl \ |
| 118 | + /shared/results/nano3-qaopd-tq |
| 119 | +``` |
| 120 | + |
| 121 | +The wrapper mounts only the specified shared root and the source checkout. The |
| 122 | +underlying `ray.sub` invocation uses exclusive nodes and disables automatic |
| 123 | +home-directory mounting inside the container. |
| 124 | + |
| 125 | +For a smoke test, copy the recipe, reduce only the number of steps and prompt |
| 126 | +count, and keep sequence length, model parallelism, quantization, top-k, and |
| 127 | +TQ dtype settings unchanged when validating memory behavior. |
0 commit comments