Tus modelos en la nube con Runpod Ollama Serverless Worker
Lanzamos Runpod Ollama serverless worker, una solución diseñada para desbloquear el poder de los modelos Ollama en la plataforma serverless de GPUs de Runpod, con APIs compatibles con OpenAI. Una forma para experimentar el poder de los modelos de lenguaje de gran tamaño (LLMs) como Llama 70B en GPUs potentes como NVIDIA A100 y A40, todo mientras mantienes los costos bajo control.
¿Por qué desarrollamos esto?
Desplegar un modelo de lenguaje de aproximadamente 70 mil millones de parámetros conlleva desafíos, incluyendo la protección de datos sensibles de la empresa al usar servicios SaaS como OpenAI, y la gestión de los altos costos de infraestructura. Ahí es donde brilla Runpod.io, ofreciendo una excelente solución de infraestructura cloud con GPUs. Runpod proporciona dos opciones de despliegue para imágenes Docker: alquilar una máquina virtual (Pod) con GPU o utilizar un worker que corre en su plataforma serverless.
Optamos por la plataforma serverless, donde solo pagas por los segundos en los que tu worker está activo procesando solicitudes y generando respuestas. La plataforma escala dinámicamente — hacia arriba o hacia abajo, incluso hasta cero — asegurando que los costos se minimizan cuando el LLM no está en uso. Cuando llega una nueva solicitud tras un período de inactividad, el worker se activa automáticamente.
Aunque Runpod ofrece workers preconfigurados como el vLLM worker, estos no soportan modelos cuantizados (comprimidos) como Llama 3.3 70B Q4 K M de Ollama, que mantiene una excelente calidad de inferencia utilizando solo el 30% de la memoria GPU de los modelos no cuantizados. Esta reducción en la demanda de recursos disminuye los costos de infraestructura y aumenta la disponibilidad de GPUs, haciendo posible el uso de chips de GPU menos potentes y más económicos.
Funcionalidades
- Despliega cualquier modelo disponible en Ollama
- API compatible con OpenAI, Chat Completions y Embeddings
- Despliegue sin servidor (serverless)
- No depende de servicios SaaS
- Soporte para streaming de respuestas
- Soporte para múltiples modelos en un solo worker
- Reemplazo de nombres de modelos (públicos vs internos)
- Compatible con Open WebUI y otras interfaces compatibles con APIs de OpenAI
Detalles Técnicos
El worker ejecuta el servidor Ollama y procesa solicitudes mediante un handler en Python que cumple con el contrato de handlers de Runpod. Aprovechamos el ruteo de request especiales que originalmente se desarrolló para el vLLM worker, que permite exponer endpoints que implementen el contrato de APIs de OpenAI.
Desarrollamos soporte para respuestas de chat con streaming e implementamos una optimización para entregar rápidamente los primeros fragmentos y luego aumentar su tamaño para optimizar el tiempo total de transferencia.
Cómo usarlo
Imagen Docker
Imágenes precompiladas
Para una prueba rápida, puedes usar una de nuestras imágenes Docker de ejemplo ya construidas:
- ingeniaca/runpod-worker-ollama:v1.0.2dev-cuda11.8.0-llama4–16x17b
- ingeniaca/runpod-worker-ollama:v1.0.2dev-cuda11.8.0-deepseek-r1_70b
- ingeniaca/runpod-worker-ollama:v1.0.2dev-cuda11.8.0-llama3.3–70b
O crea tu propia imagen
Personaliza tu imagen especificando los modelos deseados usando el parámetro — build-arg. Además, puedes definir la versión de Ollama mediante el argumento $OLLAMA_VERSION; si no lo indicas, se usará automáticamente la última versión pública disponible.
Ejemplo sin versión de Ollama especificada
docker build . - build-arg MODEL_NAME=phi3:3.8b,llama3.1:70b-instruct-q4_K_M - platform linux/amd64 -t <your_dockerhub_username>/<your_image_name>:<tag>Ejemplo con versión de Ollama especificada
docker build . --build-arg MODEL_NAME=phi3:3.8b,llama3.1:70b-instruct-q4_K_M --build-arg OLLAMA_VERSION=0.11.8 --platform linux/amd64 -t <your_dockerhub_username>/<your_image_name>:<tag>Publica tu imagen
Una vez construida, publícala en Docker Hub o el registro que prefieras:
docker image push <your_dockerhub_username>/<your_image_name>:<tag>Una vez construida, publícala en Docker Hub o el registro que prefieras:Despliega el worker
Puedes desplegar el worker de una de las siguientes maneras:
Despliegue del worker utilizando la interfaz de usuario de Runpod
En la seccion Serverless selecciona la opcion New Endpoint
Selecciona Import from Docker Registry, ya que queremos desplegar un worker personalizado.
Ingresa la imagen del worker que deseas desplegar.
Elige el tamaño y tipo de GPU, seleccionando múltiples opciones si lo necesitas. Configura variables de entorno, como los reemplazos de nombre de modelos, para simplificar las respuestas de la API.
Haz clic en Deploy Endpoint para comenzar el despliegue.
Desde la API
Para integraciones CI/CD y flujos IaC, se requiere un enfoque sistemático. Puedes utilizar la API GraphQL de Runpod. Necesitarás generar una API Key y reemplazar RUNPOD_API_KEY en los ejemplos.
Primero debes crear una “Plantilla de Endpoint”, que incluirá:
- imageName: la imagen Docker
- containerDiskInGb: el espacio requerido ajustado al modelo
- env: lista de variables de entorno
- name: nombre de la plantilla
curl --request POST \
--url 'https://api.runpod.io/graphql?api_key=RUNPOD_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"query":"mutation { saveTemplate( input: { containerDiskInGb: 70 dockerArgs: \"python handler.py\" env: [ { key: \"MODEL_NAME_OVERRIDE\" value: \"Llama 3.3 70b=llama3.3:70b-instruct-q4_K_M\" } ] imageName: \"ingeniaca/runpod-worker-ollama:v1.0.2dev-cuda11.8.0-llama3.3-70b\" isServerless: true name: \"Llama 3.3 70b Q4 K M\" readme: \"\" volumeInGb: 0 }) { id } } "}'
La respuesta incluirá el template id.
Luego puedes crear el endpoint con los siguientes parámetros:
- templateId: El ID de plantilla del paso anterior
- gpuIds: Tamaño y tipo de GPU (válidos: AMPERE_16, AMPERE_24, ADA_24, AMPERE_48, ADA_48_PRO, AMPERE_80, ADA_80_PRO)
- idleTimeout: Tiempo en segundos que el worker permanecerá activo después de una respuesta
- locations: Lista de datacenter de Runpod en donde se desplegará el worker (válidos: CZ, FR, GB, NO, RO, US)
- scalerType, scalerValue, workersMax, workersMin: Estrategia de escalado
- name: Nombre del worker
curl --request POST \
--url 'https://api.runpod.io/graphql?api_key=RUNPOD_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"query":"mutation { saveEndpoint( input: { templateId: \"iwudh9bpby\" gpuIds: \"AMPERE_48,ADA_48_PRO\" idleTimeout: 5 locations: \"\" # networkVolumeId: \"\", scalerType: \"QUEUE_DELAY\" scalerValue: 4 workersMax: 1 workersMin: 0 name: \"llama_3.3_70b -fb\" }) { id } } "}'Si el worker se despliega correctamente, recibirás el ID del worker en la respuesta. ¡En este punto ya tienes un Runpod Ollama serverless worker desplegado!
Ejemplos de llamadas a la API
Obtener modelos disponibles
Devuelve la lista de los modelos disponibles en el worker.
curl --location 'https://api.runpod.ai/v2/<runpod_worker_id>/openai/v1/models' \
--header 'Authorization: Bearer RUNPOD_API_KEYChat Completions
Solicita al modelo que responda a una consulta en una conversación de chat.
curl --location 'https://api.runpod.ai/v2/<runpod_worker_id>/openai/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer RUNPOD_API_KEY \
--data '{
"model": "llama3.3:70b-instruct-q4_K_M",
"stream": true,
"messages": [
{
"role": "user",
"content": "Could you bring 30 examples of projects that i can do with Python?"
}
],
"citations": false
}'Obtener modelos de embedding disponibles
Devuelve la lista de los modelos de embedding disponibles en el worker.
curl --location 'https://api.runpod.ai/v2/<runpod_worker_id>/openai/v1/models' \
--header 'Authorization: Bearer RUNPOD_API_KEYEmbeddings
Genera un embedding a partir de un texto.
curl --location 'https://api.runpod.ai/v2/<runpod_worker_id>/openai/v1/embeddings'
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer RUNPOD_API_KEY' \
--data '{
"model": "bge-m3:567m",
"input": "Hello world!"
}’Limitaciones
- La API solo soporta los endpoints /v1/models, /v1/chat/completions y /v1/embeddings con capacidades de streaming.
- Actualmente, la API nativa de Ollama no puede ser expuesta debido a limitaciones de la plataforma sin servidor de Runpod.
- Los tiempos de arranque pueden aumentar con modelos más grandes, pero pueden optimizarse ajustando la configuración de tiempo de inactividad.
Cierre
El Runpod Ollama serverless worker ya está disponible para la comunidad en GitHub y Docker Hub. ¡Pruébalo!
Este desarrollo que creamos desde Ingenia es escalable para cubrir muchísimas necesidades que tiene todo tipo de organizaciones.
