Logo IES Simarro
PP1-Simarro Centro de excelencia en IA y BD

Manual Spark NVFP4

Despliegue de Qwen3.5-122B-A10B con cuantización nativa NVFP4 sobre una DGX Spark. Ventana de contexto de 256k tokens aprovechando el acelerador FP4 de la arquitectura Blackwell.

¿Por qué esta configuración?

Una alternativa al Qwen3-Next 80B FP8: más parámetros, más contexto, precisión reducida por hardware.

Esta configuración explota dos características exclusivas de la arquitectura Blackwell (GB10): los Tensor Cores de 5ª generación con soporte nativo de FP4 y el acelerador de cuantización NVFP4. El formato NVFP4 —un FP4 de microbloques con escalado E4M3— preserva la calidad del modelo casi al nivel de FP8 mientras reduce el consumo de VRAM a la mitad. Esto permite cargar un modelo de 122.000 millones de parámetros (Mixture-of-Experts con 10B activos) manteniendo 256k tokens de contexto en los 128 GB unificados de la DGX Spark.

Modelo 122B A10B

Mixture-of-Experts con 122 B parámetros totales y 10 B activos por token — calidad de frontier model con coste de inferencia acotado.

Cuantización NVFP4

Formato nativo Blackwell que usa bloques FP4 con escalado FP8 — preserva calidad cercana a FP8 con la mitad de memoria.

Contexto 256k

262.144 tokens de ventana gracias al kv-cache-dtype fp8, acelerado por hardware en Blackwell.

Memoria unificada

Los 128 GB LPDDR5X compartidos CPU-GPU eliminan transferencias PCIe — todo el modelo reside en un único espacio direccionable.

Paso 1: Compilación de la imagen vLLM

Imagen base personalizada para Grace Blackwell ARM64 con soporte NVFP4.

Antes de levantar el docker-compose, hay que construir la imagen base. Se compila desde el repositorio oficial de vLLM apuntando exclusivamente a la arquitectura sm_121 (Blackwell workstation) para minimizar tiempo de compilación y tamaño final.

Bash
# Entra en la carpeta del código fuente de vLLM antes de ejecutar este build
sudo DOCKER_BUILDKIT=1 docker build . \
  -f docker/Dockerfile \
  --target vllm-openai \
  # Plataforma nativa de la CPU Grace (ARM64)
  --platform linux/arm64 \
  \
  # Exprime los 20 núcleos del Grace para acelerar la compilación
  --build-arg MAX_JOBS=20 \
  \
  # CUDA 13.0.1 + arch 12.1 = soporte nativo Blackwell (sm_121)
  --build-arg CUDA_VERSION=13.0.1 \
  --build-arg BUILD_BASE_IMAGE=nvidia/cuda:13.0.1-devel-ubuntu22.04 \
  --build-arg torch_cuda_arch_list="12.1" \
  \
  # Saltamos la verificación de wheels para ganar velocidad en el build
  --build-arg RUN_WHEEL_CHECK=false \
  \
  # Nombre final de la imagen que referenciará el docker-compose
  -t simarro-spark-vllm

Paso 2: Despliegue con Docker Compose

Orquestación de vLLM + Open WebUI servida sobre la red interna de Docker.

docker-compose.yml
# Definición de los contenedores que trabajan juntos
services:

  # ----------------------------------------------------------------
  # SERVICIO 1: vLLM (motor de inferencia)
  # ----------------------------------------------------------------
  vllm:
    # Imagen compilada localmente en el paso anterior
    image: simarro-spark-vllm
    container_name: qwen-vllm

    # Acceso completo a la memoria compartida del host — crítico para modelos grandes
    ipc: host
    restart: unless-stopped

    ports:
      - "8000:8000"

    volumes:
      # Monta la caché de HuggingFace para no re-descargar los 60+ GB del modelo
      - ~/.cache/huggingface:/root/.cache/huggingface

    # Comando de arranque (sobreescribe el CMD por defecto de la imagen vLLM)
    command: >
      --model Sehyo/Qwen3.5-122B-A10B-NVFP4
      --trust-remote-code
      --tensor-parallel-size 1
      --max-model-len 262144
      --gpu-memory-utilization 0.9
      --kv-cache-dtype fp8

    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

  # ----------------------------------------------------------------
  # SERVICIO 2: Open WebUI (interfaz tipo ChatGPT)
  # ----------------------------------------------------------------
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: qwen-webui
    restart: unless-stopped

    ports:
      - "3000:8080"

    environment:
      # Apunta a la API de vLLM usando el nombre del servicio como DNS interno
      - OPENAI_API_BASE_URL=http://vllm:8000/v1
      # Clave ficticia — el cliente la exige pero vLLM no la valida localmente
      - OPENAI_API_KEY=none
      # Desactiva el login para acceso directo en entorno local
      - WEBUI_AUTH=False

    volumes:
      - open-webui-data:/app/backend/data

    depends_on:
      vllm:
        condition: service_started

# Volúmenes globales gestionados por Docker
volumes:
  open-webui-data:

Paso 3: Desglose de los flags clave de vLLM

Qué hace cada parámetro del comando de arranque y por qué está ahí.

--model Sehyo/Qwen3.5-122B-A10B-NVFP4

Repositorio del modelo cuantizado publicado en Hugging Face. La variante A10B indica Mixture-of-Experts con 10 B de parámetros activos por token de los 122 B totales.

--trust-remote-code

Autoriza la ejecución del código Python que el repositorio del modelo incluye. Obligatorio en arquitecturas nuevas y cuantizaciones no estándar como NVFP4.

--tensor-parallel-size 1

La DGX Spark presenta una única GPU unificada Blackwell de 128 GB, por lo que no hay paralelismo de tensor: el valor correcto es 1.

--max-model-len 262144

Ventana de contexto de 256k tokens (2¹⁸). Permite caber manuales completos, bases de código enteras o varios documentos largos en un solo prompt.

--gpu-memory-utilization 0.9

Reserva el 90 % de los 128 GB unificados para vLLM. El 10 % restante queda libre para el sistema operativo y procesos auxiliares.

--kv-cache-dtype fp8

Cuantiza la caché KV (el historial de atención) a FP8. Es el "truco" que hace caber los 256k tokens junto al modelo en la VRAM — acelerado por hardware en Blackwell.

Paso 4: Arranque del stack

Levantar los contenedores y acceder a la interfaz.

Bash
# Arranca ambos servicios en segundo plano
docker compose up -d

# Sigue los logs de vLLM mientras carga el modelo (primera vez: ~10-15 min)
docker logs -f qwen-vllm

# Una vez cargado, abre la interfaz en el navegador:
#   http://<IP-de-la-Spark>:3000