VLLM API con módulos de software

De NLHPC

Introducción

En el contexto del NLHPC, se ofrecen dos herramientas principales para desplegar y realizar inferencia con LLMs: Ollama y vLLM. La elección entre ambas dependerá del formato del modelo y de los requisitos específicos de la implementación:

  • Ollama: Recomendado para utilizar modelos cuantizados. Recomendado para usuarios que no estén familiarizados con el despliegue de LLM’s dado la facilidad de uso que presenta la herramienta.
  • vLLM: Ideal para ejecutar modelos descargados desde Hugging Face en formato .safetensors, ofreciendo un alto rendimiento y eficiencia. Recomendado a usuarios con experiencia en el despliegue de LLM’s, dado la gran cantidad de parámetros ajustables que presenta la herramienta.

vLLM es un motor de inferencia y servicio de LLM’s, diseñado para ofrecer alto rendimiento y eficiencia en memoria. Su arquitectura optimizada permite ejecutar modelos de lenguaje a gran escala con aceleración GPU maximizando la respuesta en inferencias. Sin embargo, su uso es complicado dada la cantidad de parámetros a tomar en cuenta para su correcta ejecución.

En el siguiente artículo se le enseñará a:

  1. Desplegar el servicio de vLLM en el cluster utilizando módulos de software.
  2. Conectarse a la API del servicio desplegado desde su computadora local.
  3. Utilizar la API para realizar cargas de trabajo de inferencia.

Cargar módulo vLLM

Para utilizar vLLM con compatibilidad AMD realiza el export del MODULEPATH y luego carga el módulo correspondiente:

export MODULEPATH=/home/lmod/modules/all/spack/linux-rocky9-x86_64/openmpi/5.0.6-54a6qv3/aocc/5.0.0:/home/lmod/modules/all/spack/linux-rocky9-x86_64/aocc/5.0.0
ml ai-inference

El cual contiene todos paquetes de software necesarios para realizar inferencia con modelos de difusión y LLM’s.

Entre los paquetes se encuentran:

  • Pytorch,
  • Ollama,
  • vLLM,
  • diffusers,
  • huggingface-cli,
  • transformers,
  • etc

Lanzar el servicio vLLM

Ejemplo de script SBATCH para iniciar el servicio:

#!/bin/bash
#---------------Script SBATCH - NLHPC ----------------
#SBATCH -J vllm_serve
#SBATCH -p mi210
#SBATCH --gres=gpu:1
#SBATCH -n 1
#SBATCH --ntasks-per-node=1
#SBATCH -c 8
#SBATCH -t 0:10:00
#SBATCH --mem=4090MB
#SBATCH -o logs/vllm_serve_%j.out
#SBATCH -e logs/vllm_serve_%j.err
#-----------------Toolchain--------------------------
ml purge
# ----------------Modulos----------------------------
export MODULEPATH=/home/lmod/modules/all/spack/linux-rocky9-x86_64/openmpi/5.0.6-54a6qv3/aocc/5.0.0:/home/lmod/modules/all/spack /linux-rocky9-x86_64/aocc/5.0.0
ml ai-inference
# ----------------Comando--------------------------
vllm serve gpt2 --served-model-name gpt2 --distributed-executor-backend mp --tensor-parallel-size 1 --host 0.0.0.0

⚠️ Consideraciones importantes

  • Terminar el servicio de vLLM

El servicio de vLLM no termina automáticamente, recuerde siempre cancelar la tarea con scancel para evitar subutilización de recursos de cómputo

  • Memoria RAM

La cantidad de RAM que se está reservando debe ser acorde a la cantidad de memoria que necesita el modelo a lanzar. Se puede utilizar la siguiente fórmula para estimar el peso en GB

<cantidad de parámetros> * <cantidad de bits> / (8 * 10 ^ 9)

Por ejemplo, si su modelo tiene 14 billones de parámetros y está cuantizado a 4 bits, entonces requerirá 7GB de memoria para lanzarse, por tanto debe reservar siete o más gigabytes de memoria.

  • Reserva de GPU’s

Cada GPU MI210 tiene 64 GB de memoria VRAM. Si su modelo utiliza más memoria, entonces solicitar más GPU’s adicionales con --gres.

También debe agregar la flag --tensor-parallel-size <NUM_GPUS> a vllm serve.

Notar que, al solicitar más GPU’s el rendimiento en tokens/s no mejora. Además, se recomienda pedir 8 CPU’s por GPU solicitada.

  • Flags de ejecución

vLLM cuenta con una variada gama de flags para lanzar su servicio. A continuación, la guía oficial: OpenAI-Compatible Server — vLLM.

  • Puerto de escucha

El puerto por defecto es 8000. Se recomienda utilizar otro (ej. 11434) para evitar utilizar un puerto ya desplegado.

Se especifica con:

--port <Num_puerto>

al comando vllm serve.

  • Directorio de descarga de modelos

Los modelos se descargan automáticamente de HuggingFace Hub en el directorio /home/ai_inference_db/models/. Para usar y descargar modelos en su carpeta de usuario, cambie las variables de entorno:

unset HF_HOME
unset HF_DATASETS_CACHE

Además, si su modelo requiere permisos para utilizarse, puede realizar login a su cuenta utilizando:

huggingface-cli login

Por otro lado, puede comunicarse con el soporte de NLHPC vía tickets para solicitar el grupo <practica-gpu> y descargar modelos en la carpeta compartida.

  • Uso de modelos propios

Para utilizar un modelo propio o fine tunned, se debe especificar la ruta al archivo de su modelo agregando la flag --model /ruta/a/tu/modelo al comando vllm serve.

Notar que, si utiliza .gguf, el modelo debe estar en un único archivo y no dividido por partes.

Identificar el nodo de ejecución

Usa squeue para encontrar el nodo asignado:

[usuario@leftraru2 ~]$ squeue 
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
38922125 mi210 vllm_serve usuario R 0:03 1 gn004

Importante recordarlo pues lo usaremos más tarde.

Creación de túnel de acceso

Sabiendo el nodo en que ejecutó nuestra tarea. Crearemos un túnel de acceso desde el cluster hacia nuestra computadora. Para esto, en una nueva terminal, ejecutar cambiando los valores:

ssh usuario@leftraru.nlhpc.cl -p 4603 -L [puerto_local]:[nodo]:[puerto_vllm]

por ejemplo:

ssh intern02@leftraru.nlhpc.cl -p 4603 -L 4466:gn004:8000

Con esto podremos utilizar el <puerto_local> para lanzar consultas a la API de vLLM

Ejemplo de uso

Una vez realizado el túnel de acceso, podemos utilizar la API de vLLM en nuestra computadora personal, utilizando herramientas como Python o Curl.

He aqui una guia de uso para la API de vLLM.

A continuación unos ejemplos:

Python

import requests, json
url = "<http://localhost:[puerto_local]/v1/completions>"
headers = {"Content-Type": "application/json"}
payload = {
"model": "[nombre_modelo]",
"prompt": "[tu_prompt]",
"max_tokens": 100,
"temperature": 0.7
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
print(data["choices"][0]["text"])

CURL

curl -X POST "<http://localhost:[puerto_local]/v1/completions>" \
-H "Content-Type: application/json" \
squeue-d '{
"model": "[nombre_modelo]",
"prompt": "[tu_prompt]",
"max_tokens": 100,
"temperature": 0.7
}'

TroubleShooting

  • ¿Por qué el modelo no carga?

Pueden haber múltiples razones:

  1. La cantidad de GPU’s solicitadas no es divisor de la cantidad de cabezas de atención del modelo. Se recomienda que la cantidad de GPU’s sea potencia de 2.
  2. El modelo es demasiado grande y no cabe en la cantidad de GPU’s solicitadas. Se recomienda ver la documentación del modelo en hugging face y calcular cuanto pesa. Posteriormente aumentar la cantidad de GPU’s solicitadas.
  3. El modelo no está descargado en la carpeta compartida /home/ai_inference/db/models. Cambiar la carpeta utilizando unset HF_HOME y unset HF_CACHE. Pedir el grupo <practica-gpu> a soporte NLHPC para descargar modelos en la carpeta compartida.
  • ¿Puedo utilizar modelos cuantizados en vLLM?

Es posible, utilizando la flag --model /ruta/a/tu/modelo es posible cargar un LLM en formato gguf (cuantizado). Sin embargo debe ser un único archivo.

No es lo recomendado dado que vLLM está optimizado para realizar inferencia con precisión completa o media.

Otros Enlaces

OLLAMA API

VLLM API con módulos de software

VLLM API con apptainer

Diffusers