Hacer CI con GPUs y runners confiables sin mantener servidores suena caro y complejo, ¿no? Pues no tiene por qué serlo. En este artículo técnico te muestro paso a paso cómo conectar tus workflows de GitHub Actions para que se ejecuten en Hugging Face Jobs, manteniendo GitHub como orquestador pero usando la infraestructura de HF para ejecutar las tareas reales.
Por qué querrías esto
GitHub Actions da una máquina por defecto con runs-on: ubuntu-latest. Conveniente, sí; perfecto para todo, no tanto. Limitaciones comunes:
- Latencia o caídas por mantenimientos de GitHub.
- Imágenes genéricas sin tooling específico.
- Acceso a GPU casi imposible para proyectos open source.
¿Te imaginas correr la misma batería de tests en una GPU real sin mantener un runner propio? Trackio lo hizo: redujo tiempos en jobs CPU alrededor de 30% y añadió una suite de tests en GPU que antes era inviable.
Arquitectura básica y idea central
La idea es simple y elegante: seguir usando GitHub Actions para definir flujos, pero ejecutar los pasos en Jobs de Hugging Face. Para eso se crea un puente: un dispatcher que recibe el webhook workflow_job.queued del App de GitHub y arranca un HF Job que actúa como runner efímero.
Componentes clave:
- Un Space llamado
jobs-actions-dispatcherque recibe webhooks y lanza Jobs. - Un GitHub App que escucha jobs encolados y crea tokens temporales de registro de runners.
- HF Jobs que lanzan contenedores con el hardware necesario (CPU o GPU).
Desde GitHub parece un runner self-hosted. Desde Hugging Face es un Job que ejecuta los pasos del workflow.
Configuración paso a paso
- Duplicar el dispatcher Space
- Ve a
huggingface/jobs-actions-dispatchery duplica el Space. - Owner: tu usuario u organización HF.
- Name:
jobs-actions-dispatcher. - Hardware: usa
cpu-upgradepara producción;cpu-basicvale para pruebas pero puede quedarse dormido.
Si prefieres CLI:
export HF_NAMESPACE=tu-usuario-o-org
export SPACE_ID="$HF_NAMESPACE/jobs-actions-dispatcher"
hf repo duplicate huggingface/jobs-actions-dispatcher "$SPACE_ID" \
--type space \
--flavor cpu-upgrade \
--exist-ok
export DISPATCHER_URL="https://$HF_NAMESPACE-jobs-actions-dispatcher.hf.space"
- Crear e instalar el GitHub App
- Abre el Space duplicado; en la UI aparece el webhook URL que necesitas para el App.
- En el formulario pon el repo al que quieres conectar: YOUR-GITHUB-ORG/YOUR-REPO.
- Crea el GitHub App desde la UI. El App necesita permisos para escuchar jobs encolados y crear tokens de registro de runners.
- Sube las credenciales del App al Space usando las instrucciones que genera el Space.
Importante: guarda en los secrets del Space un HF_TOKEN con permisos para lanzar Jobs; ese token determina bajo qué namespace se facturarán los Jobs.
- Opcional: cambiar namespace de facturación
Si quieres facturar Jobs a otro usuario u org:
export SPACE_ID=TU-HF-NAMESPACE/jobs-actions-dispatcher
hf spaces variables add "$SPACE_ID" -e HF_NAMESPACE=tu-billing-namespace
hf spaces restart "$SPACE_ID"
- Cambia tus workflows de GitHub
La modificación es mínima. Sustituye el runs-on: ubuntu-latest por una etiqueta gestionada por el dispatcher, por ejemplo:
- CPU:
runs-on: hf-jobs-cpu-upgrade - GPU:
runs-on: hf-jobs-t4-small
Ejemplo de workflow minimalista:
name: HF Jobs Test
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
jobs:
test:
runs-on: hf-jobs-cpu-upgrade
steps:
- uses: actions/checkout@v4
- run: echo 'Hello from Hugging Face Jobs'
Luego commitea y haz push. El dispatcher se encargará de lanzar un HF Job que registre un runner efímero y ejecute el workflow.
Verificación y comandos útiles
Desde la CLI puedes comprobar el estado con:
gh run list --repo YOUR-GITHUB-ORG/YOUR-REPO --limit 5
hf jobs ps --namespace "$HF_NAMESPACE"
hf spaces logs "$SPACE_ID"
Los logs se ven como en una Action normal, y además puedes obtenerlos directamente con hf jobs logs <job_id> > logs.txt para analizarlos localmente.
Imágenes Docker y rendimiento: lecciones prácticas
No uses una ubuntu:22.04 vacía si necesitas tooling: te tocará instalar Playwright, Node, ffmpeg, sqlite, git y dependencias en cada corrida.
Trackio cambió a la imagen de Playwright y a una imagen CUDA para GPU:
- CPU image:
mcr.microsoft.com/playwright:v1.60.0-jammy - GPU image:
nvidia/cuda:12.4.0-runtime-ubuntu22.04
Resultados reportados por Trackio:
| Runner setup | Runtime | Comparado con GitHub promedio |
|---|---|---|
| GitHub ubuntu-latest baseline | 1m40s | baseline |
| HF Jobs CPU con Playwright image | 1m10s | -30s, ~30% más rápido |
| HF Jobs GPU, t4-small label | 45s | no hay baseline GPU en GitHub |
La ganancia clave fue poder ejecutar tests en GPU reales: 45s y costando menos de un centavo según la tarifa t4-small para esa duración.
Buenas prácticas y trucos
- Usa una imagen Docker que ya incluya el tooling que necesitas para evitar instalar dependencias en cada run.
- Si necesitas datasets o modelos rápidos, HF Jobs permite montar volúmenes.
- Ten cuidado con el dispatcher en
cpu-basicsi lo usas en producción: podría dormirse y dejar workflows encolados. - Mantén el
HF_TOKENcon el scope mínimo: permisos para lanzar Jobs solo en el namespace necesario.
Pequeño tip: en nuestro puente también reflejamos los logs de GitHub en el HF Job y viceversa, así no pierdes contexto ni en GitHub ni en HF.
Conclusión práctica
Si tu proyecto necesita controles más finos sobre hardware, imágenes o acceso a aceleradores, usar Hugging Face Jobs como backend para GitHub Actions es una solución práctica y escalable. Requiere un componente inicial (el dispatcher Space y el GitHub App), pero la integración diaria es solo cambiar runs-on por una etiqueta.
¿Quieres ahorro de tiempo, acceso a GPUs y logs fáciles de descargar? Este flujo puede darte todo eso sin complicarte con runners permanentes.
