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.

Note

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.

    Note

    DGX 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

  1. Open a terminal on your DGX Spark system, and log in to registry.redhat.io:

    $ podman login registry.redhat.io
  2. Pull 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.2
    Note

    DGX Spark uses the same vllm-cuda-rhel9 container image as data center NVIDIA GPUs. The container registry automatically provides the AArch64 image variant for the DGX Spark ARM architecture.

  3. If your system has SELinux enabled, configure SELinux to allow device access:

    $ sudo setsebool -P container_use_devices 1
    Note

    DGX OS uses AppArmor instead of SELinux. Skip this step if you are running DGX OS.

  4. 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-cache
  5. Append your HF_TOKEN Hugging Face token to the private.env file. Source the private.env file.

    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.env
  6. Verify 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-smi

    The output lists the NVIDIA GB10 GPU. DGX Spark uses unified memory shared between the CPU and GPU, so the Memory-Usage fields show N/A because the GPU does not have dedicated memory that can be reported separately. This is expected and confirms that the container can access the GPU.

  7. 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 fastsafetensors

    Where:

    --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-size to 8GB if 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_TOKEN with your Hugging Face token.
    -v ./rhaii-cache:/opt/app-root/src/.cache:Z
    Mounts the cache directory with SELinux context. The :Z suffix is required for systems where SELinux is enabled. On DGX OS, Ubuntu, Debian, or Docker without SELinux, omit the :Z suffix.
    --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.9 prevents 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.
    Note

    If you are running RHEL on DGX Spark, add -e LD_PRELOAD= to the podman run command 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.

  8. 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 | jq

    Example 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
        }
    }

5.1. Tuning vLLM for NVIDIA DGX Spark

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

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

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.

Table 5.1. Recommended vLLM serve parameters for DGX Spark
ParameterRecommended valueDefault valueDescription

--gpu-memory-utilization

0.85

0.9

Fraction of GPU memory that vLLM allocates for model weights, activations, and KV cache. On DGX Spark, set this below 0.9 to reserve memory for the operating system, page cache, and container runtime. A starting value of 0.85 provides approximately 19 GB for KV cache with a 7B-parameter FP8 model. If you experience out-of-memory crashes, lower this value further. If your workload is stable and you need more KV cache capacity, you can increase this value up to 0.92 with careful monitoring.

--tensor-parallel-size

1

1

Number of GPUs to use for tensor parallelism. DGX Spark has a single integrated GPU. Setting this to any value greater than 1 causes a startup failure.

--max-num-seqs

1 - 4

256

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 1 or 2. For batch workloads, set this to 4.

--max-model-len

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.

--load-format

fastsafetensors

auto

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 fastsafetensors for reliable weight loading that completes in approximately 1 second.

Note

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

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 --quantization flag 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 marlin when 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

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.

Table 5.2. Model sizing guidance for DGX Spark
Model categoryExample models--gpu-memory-utilization--max-num-seqsNotes

Small MoE, 3-4B active parameters

Mixtral 8x7B NVFP4, Qwen3-30B-A3B

0.85

4

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

0.85 - 0.90

1 - 2

Requires NVFP4 quantization to fit within the memory budget. Pass --moe-backend marlin.

Dense, 7B-8B parameters

Llama 3.1 8B FP8, Granite 3.1 8B FP8

0.85

4

FP8 models fit with generous KV cache headroom.

Dense, 13B-27B parameters

Gemma 2 27B FP8, Mistral Small 24B NVFP4

0.85 - 0.90

1 - 2

NVFP4 quantization recommended for models above 13B. Reduce --max-model-len if the default context length is large.

Dense, 70B parameters

Llama 3.3 70B NVFP4

0.90 - 0.92

1

Requires NVFP4 quantization. Reduce --max-model-len to 4096 or lower to fit within memory. Monitor for memory pressure.

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.

Table 5.3. Approximate KV cache budget for a 7B FP8 model on DGX Spark
--gpu-memory-utilizationTotal memory allocated to vLLMApproximate KV cache budget

0.50

64 GB

~50 GB

0.70

90 GB

~76 GB

0.80

102 GB

~88 GB

0.85

109 GB

~95 GB

0.90

115 GB

~101 GB

0.92

118 GB

~104 GB

Note

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

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 fastsafetensors to use the fastsafetensors weight loader, which completes loading in approximately 1 second.
Out-of-memory crashes from the default --gpu-memory-utilization value
The vLLM default of 0.9 allocates 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-utilization to 0.85 or lower when deploying on DGX Spark.
Page cache contention
Even without an out-of-memory crash, setting --gpu-memory-utilization too 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 your podman run command to clear the preload. This does not affect vLLM serving performance. DGX OS and Ubuntu use 4K pages and are not affected.
Incorrect --moe-backend for 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-size greater than 1
DGX Spark has a single GPU. Setting --tensor-parallel-size to any value greater than 1 causes a startup failure because vLLM cannot find additional GPU devices.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top