Chapter 5. Serve and inference language models with Podman on NVIDIA DGX Spark
You can serve language models and run inference with Podman on NVIDIA DGX Spark. The DGX Spark is powered by the GB10 Grace Blackwell Superchip, which combines an ARM aarch64 CPU and a Blackwell GPU with 128 GB of unified LPDDR5x memory. Unlike data center GPUs with dedicated high-bandwidth memory, DGX Spark shares its entire memory pool between the CPU, GPU, operating system, and container runtime. This unified memory architecture requires adjusted vLLM parameters to avoid out-of-memory conditions.
DGX Spark is a single-GPU system. Multi-GPU features such as tensor parallelism across devices, NVLink, NVSwitch, and Fabric Manager do not apply to DGX Spark deployments.
Prerequisites
- You have an NVIDIA DGX Spark GB10 system or an OEM variant based on the GB10 Grace Blackwell Superchip.
- Your system runs Red Hat Enterprise Linux (RHEL) or DGX OS based on Ubuntu 24.04.
NVIDIA driver 580.65.06 or later is installed with the open source GPU kernel modules.
NoteDGX OS includes driver 580.95.05 pre-installed, which meets this requirement. If you are running RHEL on DGX Spark, you must install the drivers separately. For more information, see Building a custom RHEL kernel for NVIDIA DGX Spark.
- NVIDIA Container Toolkit 1.14 or later is installed.
- Podman is installed and configured.
-
You have access to
registry.redhat.io. - You have a Hugging Face account and have generated a Hugging Face access token.
Procedure
Open a terminal on your DGX Spark system, and log in to
registry.redhat.io:$ podman login registry.redhat.ioPull the Red Hat AI Inference CUDA container image by running the following command:
$ podman pull registry.redhat.io/rhaii-early-access/vllm-cuda-rhel9:3.5.0-ea.2NoteDGX Spark uses the same
vllm-cuda-rhel9container image as data center NVIDIA GPUs. The container registry automatically provides the AArch64 image variant for the DGX Spark ARM architecture.If your system has SELinux enabled, configure SELinux to allow device access:
$ sudo setsebool -P container_use_devices 1NoteDGX OS uses AppArmor instead of SELinux. Skip this step if you are running DGX OS.
Create a volume and mount it into the container. Adjust the container permissions so that the container can use it.
$ mkdir -p rhaii-cache$ chmod g+rwX rhaii-cacheAppend your
HF_TOKENHugging Face token to theprivate.envfile. Source theprivate.envfile.In the following command, replace
<your_HF_token>with your Hugging Face access token:$ echo "export HF_TOKEN=<your_HF_token>" > private.env$ source private.envVerify that the Red Hat AI Inference container can access the NVIDIA GPU on the host by running the following command:
$ podman run --rm -it \ --security-opt=label=disable \ --device nvidia.com/gpu=all \ registry.redhat.io/{rhaii-registry-namespace}/vllm-cuda-rhel9:{rhaiis-version} \ nvidia-smiThe output lists the NVIDIA GB10 GPU. DGX Spark uses unified memory shared between the CPU and GPU, so the
Memory-Usagefields showN/Abecause the GPU does not have dedicated memory that can be reported separately. This is expected and confirms that the container can access the GPU.Start the AI Inference container image.
$ podman run --rm -it \ --device nvidia.com/gpu=all \ --security-opt=label=disable \ --shm-size=4g -p 8000:8000 \ --userns=keep-id:uid=1001 \ --env "HUGGING_FACE_HUB_TOKEN=$HF_TOKEN" \ --env "HF_HUB_OFFLINE=0" \ -v ./rhaii-cache:/opt/app-root/src/.cache:Z \ registry.redhat.io/rhaii-early-access/vllm-cuda-rhel9:3.5.0-ea.2 \ --model RedHatAI/Llama-3.2-1B-Instruct-FP8 \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.85 \ --max-num-seqs 4 \ --load-format fastsafetensorsWhere:
--security-opt=label=disable- Disables SELinux label relabeling for volume mounts. Required for systems where SELinux is enabled. Without this option, the container might fail to start.
--shm-size=4g -p 8000:8000-
Specifies the shared memory size and port mapping. Increase
--shm-sizeto8GBif you experience shared memory issues. --userns=keep-id:uid=1001-
Maps the host UID to the effective UID of the vLLM process in the container. Alternatively, you can pass
--user=0, but this is less secure because it runs vLLM as root inside the container. --env "HUGGING_FACE_HUB_TOKEN=$HF_TOKEN"-
Specifies the Hugging Face API access token. Set and export
HF_TOKENwith your Hugging Face token. -v ./rhaii-cache:/opt/app-root/src/.cache:Z-
Mounts the cache directory with SELinux context. The
:Zsuffix is required for systems where SELinux is enabled. On DGX OS, Ubuntu, Debian, or Docker without SELinux, omit the:Zsuffix. --tensor-parallel-size 1-
Specifies the number of GPUs to use for tensor parallelism. DGX Spark has a single integrated GPU, so this value must be
1. --gpu-memory-utilization 0.85-
Specifies the fraction of GPU memory that vLLM can use for model weights, activations, and KV cache. On DGX Spark, the 128 GB memory pool is shared between the CPU, GPU, operating system, and container runtime. Setting this value below the default of
0.9prevents memory contention that can cause out-of-memory crashes. For more guidance on adjusting this value, see Tuning vLLM for NVIDIA DGX Spark. --max-num-seqs 4- Limits the maximum number of sequences processed concurrently. A lower value reduces memory pressure on the single-GPU workstation and improves per-request latency.
--load-format fastsafetensors- Uses the fastsafetensors weight loader instead of the default mmap-based safetensors loader. The default loader can hang during weight loading on DGX Spark due to the unified memory architecture and filesystem behavior. The fastsafetensors loader completes weight loading in approximately 1 second.
NoteIf you are running RHEL on DGX Spark, add
-e LD_PRELOAD=to thepodman runcommand to clear the jemalloc preload. The container image preloads a jemalloc build compiled for 4K memory pages, but RHEL on DGX Spark defaults to 64K memory pages. Without this override, the container stops immediately on startup. This setting does not affect vLLM serving performance. DGX OS and Ubuntu use 4K pages and are not affected.In a separate tab in your terminal, send a test request to the model server
$ curl -X POST -H "Content-Type: application/json" -d '{ "prompt": "What is the capital of France?", "max_tokens": 50 }' http://localhost:8000/v1/completions | jqExample output
{ "id": "cmpl-b84aeda1d5a4485c9cb9ed4a13072fca", "object": "text_completion", "created": 1746555421, "model": "RedHatAI/Llama-3.2-1B-Instruct-FP8", "choices": [ { "index": 0, "text": " Paris.\nThe capital of France is Paris.", "logprobs": null, "finish_reason": "stop", "stop_reason": null, "prompt_logprobs": null } ], "usage": { "prompt_tokens": 8, "total_tokens": 18, "completion_tokens": 10, "prompt_tokens_details": null } }
Next steps
5.1. Tuning vLLM for NVIDIA DGX Spark Copy linkLink copied to clipboard!
You can optimize Red Hat AI Inference performance on NVIDIA DGX Spark by adjusting vLLM server arguments for the unified memory architecture. DGX Spark differs from data center GPUs because the CPU, GPU, operating system, page cache, and container runtime share a single 128 GB LPDDR5x memory pool instead of using separate high-bandwidth GPU memory. Applying data center GPU defaults to DGX Spark causes out-of-memory crashes because vLLM attempts to allocate more memory than the shared pool can provide after accounting for operating system and container runtime consumption.
5.1.1. DGX Spark memory architecture Copy linkLink copied to clipboard!
The NVIDIA DGX Spark GB10 Grace Blackwell Superchip combines an ARM aarch64 CPU and a Blackwell GPU with Compute Capability 12.1 into a single system-on-chip. Both the CPU and GPU access the same 128 GB LPDDR5x memory at up to 273 GB/s.
Because there is no dedicated GPU memory, the available memory for vLLM model weights, activations, and KV cache depends on how much memory the operating system, page cache, and container runtime are consuming at any given time. If vLLM allocates too aggressively, the system can enter memory contention where the Linux kernel starts reclaiming pages from the page cache, which degrades I/O performance for all processes. In severe cases, the Out-of-Memory killer terminates the vLLM process.
DGX Spark also has a single GPU with 48 streaming multiprocessors and 6,144 CUDA cores. Tensor parallelism across multiple GPUs is not possible. Inference decode throughput on DGX Spark is memory-bandwidth-bound because the 273 GB/s bandwidth is significantly lower than the multi-terabyte bandwidth available on data center GPUs with HBM.
5.1.2. Key vLLM serve parameters for DGX Spark Copy linkLink copied to clipboard!
The following table lists the vLLM server arguments that you should adjust for DGX Spark deployments. Pass these arguments to the vllm serve entrypoint when starting the AI Inference container.
| Parameter | Recommended value | Default value | Description |
|---|---|---|---|
|
|
|
|
Fraction of GPU memory that vLLM allocates for model weights, activations, and KV cache. On DGX Spark, set this below |
|
|
|
|
Number of GPUs to use for tensor parallelism. DGX Spark has a single integrated GPU. Setting this to any value greater than |
|
|
|
|
Maximum number of sequences processed concurrently. Lower values reduce peak memory consumption and improve per-request latency on a single-GPU workstation. For interactive workloads with one or two users, set this to |
|
| Varies by model | Model default | Maximum context length in tokens. If a model defines a large default context length, vLLM pre-allocates KV cache memory for that length. Reduce this value to free memory for model weights or to fit larger models. |
|
|
|
|
Weight loading method. The default mmap-based safetensors loader can hang during weight loading on DGX Spark due to the unified memory architecture and filesystem behavior. Use |
If you are running RHEL on DGX Spark, set the environment variable LD_PRELOAD= (empty value) in the container to clear the jemalloc preload. The container image preloads a jemalloc build compiled for 4K memory pages, but RHEL on DGX Spark defaults to 64K memory pages, which causes the container to stop immediately on startup. Add -e LD_PRELOAD= to your podman run command. This setting does not affect vLLM serving performance. DGX OS and Ubuntu use 4K pages and are not affected.
5.1.3. Data type and quantization guidance Copy linkLink copied to clipboard!
DGX Spark uses the Blackwell architecture with Compute Capability 12.1, which introduces native support for narrow data types that reduce model memory footprint and improve throughput.
- NVFP4
-
NVFP4 is the preferred quantization format for DGX Spark. Blackwell Tensor Cores accelerate FP4 matrix operations natively, so pre-quantized NVFP4 model checkpoints achieve the best balance of quality and performance. When you use a pre-quantized NVFP4 checkpoint, leave the
--quantizationflag unset because vLLM detects the quantization format automatically from the model configuration. - FP8
- FP8 quantization is also supported. Pre-quantized FP8 checkpoints run without any additional flags.
- MoE models
-
Mixture-of-Experts models on DGX Spark with Compute Capability 12.1 require the Marlin backend. Pass
--moe-backend marlinwhen serving MoE models. Without this flag, the default MoE backend can fail or produce incorrect results on the sm_121 architecture.
5.1.4. Model sizing for 128 GB unified memory Copy linkLink copied to clipboard!
The following table provides guidance on model sizes and recommended parameters for DGX Spark. Actual memory consumption varies by model architecture, quantization method, and context length.
| Model category | Example models | --gpu-memory-utilization | --max-num-seqs | Notes |
|---|---|---|---|---|
| Small MoE, 3-4B active parameters | Mixtral 8x7B NVFP4, Qwen3-30B-A3B |
|
| Only the active parameter subset is loaded for each token. NVFP4 checkpoints fit comfortably. |
| Large MoE, 10-15B active parameters | DeepSeek-V3 NVFP4, Mixtral 8x22B NVFP4 |
|
|
Requires NVFP4 quantization to fit within the memory budget. Pass |
| Dense, 7B-8B parameters | Llama 3.1 8B FP8, Granite 3.1 8B FP8 |
|
| FP8 models fit with generous KV cache headroom. |
| Dense, 13B-27B parameters | Gemma 2 27B FP8, Mistral Small 24B NVFP4 |
|
|
NVFP4 quantization recommended for models above 13B. Reduce |
| Dense, 70B parameters | Llama 3.3 70B NVFP4 |
|
|
Requires NVFP4 quantization. Reduce |
5.1.5. KV cache budget at different memory utilization levels Copy linkLink copied to clipboard!
The following table shows the approximate memory available for KV cache at different --gpu-memory-utilization values after loading a 7B-parameter FP8 model. Use this table to estimate how much context length and concurrency your deployment can support.
--gpu-memory-utilization | Total memory allocated to vLLM | Approximate KV cache budget |
|---|---|---|
|
| 64 GB | ~50 GB |
|
| 90 GB | ~76 GB |
|
| 102 GB | ~88 GB |
|
| 109 GB | ~95 GB |
|
| 115 GB | ~101 GB |
|
| 118 GB | ~104 GB |
These values are estimates. Actual KV cache capacity depends on the model architecture, sequence length, number of attention heads, and head dimension. The operating system, page cache, and container runtime typically consume 10-15 GB from the 128 GB total, which reduces the memory available for --gpu-memory-utilization to allocate.
5.1.6. Common pitfalls Copy linkLink copied to clipboard!
The following issues are specific to DGX Spark deployments.
- Weight loading hangs with the default safetensors loader
-
The default mmap-based safetensors loader can hang at 0% during weight loading on DGX Spark due to the unified memory architecture and filesystem behavior. Always pass
--load-format fastsafetensorsto use the fastsafetensors weight loader, which completes loading in approximately 1 second. - Out-of-memory crashes from the default
--gpu-memory-utilizationvalue -
The vLLM default of
0.9allocates approximately 115 GB of the 128 GB memory pool. Combined with operating system and container runtime memory consumption, this leaves almost no free memory and triggers the Linux Out-of-Memory killer. Always set--gpu-memory-utilizationto0.85or lower when deploying on DGX Spark. - Page cache contention
-
Even without an out-of-memory crash, setting
--gpu-memory-utilizationtoo high can evict the Linux page cache. This causes slower file I/O operations, including model weight loading and checkpoint downloads. If model loading is unusually slow, lower--gpu-memory-utilization. - Container stops on RHEL with 64K-page kernel
-
The container image preloads a jemalloc build compiled for 4K memory pages. RHEL on DGX Spark defaults to a 64K-page kernel, which causes jemalloc to stop immediately on startup. Add
-e LD_PRELOAD=to yourpodman runcommand to clear the preload. This does not affect vLLM serving performance. DGX OS and Ubuntu use 4K pages and are not affected. - Incorrect
--moe-backendfor MoE models -
Mixture-of-Experts models on DGX Spark require
--moe-backend marlin. Without this flag, inference can fail or produce incorrect output on Compute Capability 12.1. - Setting
--tensor-parallel-sizegreater than 1 -
DGX Spark has a single GPU. Setting
--tensor-parallel-sizeto any value greater than1causes a startup failure because vLLM cannot find additional GPU devices.