En este artículo vamos a dar una visión general de Seldon, una herramienta open-source para el despliegue y la productivización de modelos de Machine Learning, que está ganando mucha popularidad y cada vez está siendo más usada en el mundo MLOps.

Lo primero que tenemos que comentar es que Seldon está desarrollado y mantenido por la compañía británica Seldon Technologies que lo que realmente ofrece como producto open source es Seldon Core y por encima ofrece otro tipo de herramientas como Seldon Deploy.

Como vemos en la imagen Seldon se despliega sobre Kubernetes o sobre OpenShift ya sea on premise o en cualquier servicio gestionado en Cloud. Esta es una de sus características más interesantes ya que así aprovecha todas las ventajas de escalabilidad, gestión de recursos y estandarización que hacen de Kubernetes una plataforma líder para la orquestación de contenedores.

Otra de las grandes ventajas de Seldon es la capacidad de integración e interoperabilidad que tiene a la hora de trabajar con modelos desarrollados con diferentes lenguajes y herramientas, así como con servicios en la nube. En este artículo veremos algunos ejemplos con Python, Scikit learn, Tensorflow, AWS y Google Cloud.

Todo modelo desplegado con Seldon, finalmente será expuesto y explotado a través de un API (REST, gRPC) y monitorizado de una forma integrada en producción.

A continuación vamos a ver paso a paso cómo instalar Seldon en AWS y ponerlo a trabajar con un par de ejemplos sencillos. En el primer ejemplo desplegaremos un modelo entrenado con scikit-learn para clasificar flores iris. En el segundo ejemplo veremos cómo entrenar una red neuronal con Tensorflow para la clasificación de dígitos manuscritos y cómo encapsular dicho modelo y desplegarlo con Seldon.

Desplegando e instalando Seldon

La instalación de Seldon es relativamente sencilla a pesar de ser una herramienta que maneja gran complejidad interna y que ejecuta sobre Kubernetes.

En este caso y a modo de ejemplo vamos a realizar un despliegue en pocos pasos de Seldon sobre un cluster gestionado de Kubernetes en AWS. De forma similar podríamos instalarlos en cualquier otro servicio de Kubernetes cloud u on-premise.

Lo primero que necesitamos es un cluster de Kubernetes, para ello vamos a levantar en EKS, el servicio gestionado de Kubernetes de AWS. Gracias a la herramienta eksctl de AWS podemos desplegar con un solo comando en minutos un cluster básico de Kubernetes en cloud. Por ejemplo, para nuestro caso vamos a levantar un cluster de 3 nodos en la región de Irlanda y le indicaremos nuestra clave pública para poder acceder más tarde por ssh:

$ eksctl create cluster --region eu-west-1 --name seldon-cluster --nodes 3 --ssh-public-key "~/.ssh/id_rsa.pub"

La herramienta eksctl usa por debajo el sistema de plantillas y despliegues CloudFormation de AWS que gestiona de forma transparente todas las dependencias de infraestructura de nuestro cluster. Podemos encontrar más información detallada sobre cómo levantar clusters de Kubernetes con eksctl y todas las opciones disponibles en la documentación oficial.

Pasados unos minutos tendremos disponible nuestro cluster y podremos interactuar con él.

A continuación instalaremos Ambassador para que funcione como gateway a la hora de dirigir nuestra peticiones a Seldon, también podemos usar Istio como alternativa.

Para instalar Ambassador añadiremos el repositorio y lo instalaremos en Kubernetes vía helm:

$ helm repo add datawire https://getambassador.io
$ helm install ambassador datawire/ambassador

A partir de este punto usaremos la herramienta kubectl para interactuar con nuestro cluster de Kubernetes. Kubectl es una herramienta de línea de comandos que nos permite realizar multitud de operaciones sobre nuestro cluster: gestionar los recursos, desplegar aplicaciones, obtener logs, exponer servicios y otras muchas operaciones. En este artículo podemos profundizar un poco más en Kubernetes y sus capacidades.

El siguiente paso será crear un namespace a través de kubectl para la instalación de Seldon:

$ kubectl create namespace seldon-system

Finalmente instalaremos Seldon también vía helm en el namespace seldon-system, importante añadir el flag para activar el uso de Ambassador:

$ helm install seldon-core seldon-core-operator --repo https://storage.googleapis.com/seldon-charts --set ambassador.enabled=true --set usageMetrics.enabled=true --namespace seldon-system

Podemos confirmar que Seldon se ha desplegado correctamente con el siguiente comando que muestra el estado de los pods para un namespace:

$ kubectl get pods --namespace seldon-system
NAME                                         READY   STATUS    RESTARTS   AGE
seldon-controller-manager-6c4f88cb58-t56z7   1/1     Running   0          2m3s

Deberíamos de ver un pod llamado “seldon-controller-manager-xxx” en estado “Running”.

Con estos pasos ya tendremos instalado y disponible Seldon, ahora veremos cómo desplegar con Seldon un modelo de Machine Learning sencillo.

Desplegar un modelo de Scikit-learn

El primer paso para desplegar un modelo de Machine Learning con Seldon es crear un namespace en Kubernetes dentro del cual desplegaremos nuestros modelos. En este caso crearemos uno llamado “seldon”:

$ kubectl create namespace seldon

A continuación desplegaremos a través de “kubectl apply” pasándole como argumento un fichero yaml con la definición de nuestro modelo:

$ kubectl apply -f model.yaml

Echemos un ojo al contenido del fichero yaml:

apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
  name: iris-model
  namespace: seldon
spec:
  name: iris
  predictors:
  - graph:
      implementation: SKLEARN_SERVER
      modelUri: gs://seldon-models/sklearn/iris
      name: classifier
    name: default
    replicas: 1

Para este ejemplo básico nos apoyaremos en SKLearn Server el servidor pre-empaquetado que trae Seldon para servir modelos de Scikit-learn. Además proporcionaremos la uri de un modelo ya preparado por el equipo de desarrollo de Seldon que se encuentra en bucket público de Google Cloud Storage y que contiene un modelo de clasificación entrenado con Scikit-learn para el problema clásico de clasificación de flores iris en formato pickle.

Una vez tengamos desplegado nuestro modelo ya podremos empezar a lanzarle peticiones, en este caso predicciones sobre de qué tipo de flor se trata.

Para averiguar la url de nuestro endpoint en Ambassador podemos ejecutar el siguiente comando:

$ kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
xxx.eu-west-1.elb.amazonaws.com}

Y con esta información ya podremos lanzar una petición a través de cualquier cliente http o directamente con cURL.

En este ejemplo con el modelo de clasificación de la flor iris, al clasificador se le proporcionan 4 propiedades morfológicas de una flor dada y el clasificador nos hará una predicción de a qué subespecie de las 3 posibles (Iris Setosa, Iris Versicolor, Iris Virgínica) corresponde dicha flor observada.

En este caso, imaginemos que tenemos una flor con estas propiedades:

La petición con cURL contra nuestro modelo desplegado con Seldon sería la siguiente:

$ curl -k -X POST "https://a58d7aead97304ba5954fe82abfcd81b-1490783467.eu-west-1.elb.amazonaws.com/seldon/seldon/iris-model/api/v1.0/predictions" -H "Content-Type: application/json" -d '{"data":{"ndarray":[[6.1,  2.8,  4.7,  1.2]]}}'

Y la respuesta obtenida:

{"data":{"names":["t:0","t:1","t:2"],"ndarray":[[0.008724203775254364,0.7055869744463771,0.28568882177836846]]},"meta":{"requestPath":{"classifier":"seldonio/sklearnserver:1.6.0"}}}

Como vemos en la respuesta, la mayor confianza (0,7) se obtiene para la subespecie “1” que se corresponde con “Iris Versicolor”. Por lo tanto nuestro clasificador cree que esta flor es una Iris Versicolor.

Además Seldon nos ofrece a través de Swagger la posibilidad de navegar cómodamente por el API expuesta por nuestros modelos, lo que puede ser muy útil para explorarla. En este caso podríamos verla en un navegador a través de:

https://xxx.eu-west-1.elb.amazonaws.com/seldon/seldon/iris-model/api/v1.0/doc/

Entrenar y desplegar un modelo de Tensorflow

El siguiente paso sería desplegar un modelo entrenado por nosotros mismos. Para el siguiente ejemplo vamos a entrenar con Tensorflow un modelo clásico de detección de dígitos manuscritos con el bien conocido dataset MNIST. Después desplegaremos y serviremos este modelo con Seldon a través del servidor de Tensorflow integrado.

El primer paso será entrenar una sencilla red con el dataset de MNIST disponible desde el propio API de Tensorflow. Guardaremos el resultado del modelo entrenado para el siguiente paso.

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)

tf.saved_model.save(model, 'mnist-model/1')

La estructura de ficheros de nuestro modelo guardado será la siguiente:

$ tree model/
model/
└── 1
    ├── assets
    ├── saved_model.pb
    └── variables
        ├── variables.data-00000-of-00001
        └── variables.index

El siguiente paso será subir nuestro modelo entrenado a un servicio de almacenamiento en la nube. En estos momentos Seldon soporta Google Cloud Storage, AWS S2 y Azure Blob Storage como sistemas de almacenamiento para modelos pre empaquetados.

Nosotros, por ejemplo, lo subiremos a un bucket de Google Cloud Storage, lo podemos hacer directamente desde la consola de Google Cloud o con la herramienta gsutil de Google Cloud. Finalmente deberíamos de obtener una estructura como la siguiente en nuestro bucket:

$ gsutil ls -R gs://paradigma-seldon/
gs://paradigma-seldon/tfserving/:
gs://paradigma-seldon/tfserving/

gs://paradigma-seldon/tfserving/mnist-model/:
gs://paradigma-seldon/tfserving/mnist-model/

gs://paradigma-seldon/tfserving/mnist-model/1/:
gs://paradigma-seldon/tfserving/mnist-model/1/saved_model.pb

gs://paradigma-seldon/tfserving/mnist-model/1/variables/:
gs://paradigma-seldon/tfserving/mnist-model/1/variables/variables.data-00000-of-00001
gs://paradigma-seldon/tfserving/mnist-model/1/variables/variables.index

Ahora ha llegado el momento de escribir el fichero YAML que describe el despliegue de nuestro modelo entrenado con Tensorflow. Una versión mínima sería la siguiente:

apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
  name: tfserving
  namespace: seldon
spec:
  name: mnist
  predictors:
  - graph:
      children: []
      implementation: TENSORFLOW_SERVER
      modelUri: gs://paradigma-seldon/tfserving/mnist-model
      name: mnist-model
      parameters: []

    name: default
    replicas: 1

En este caso es importante destacar que el parámetro “implementation” lo fijaremos a “TENSORFLOW_SERVER” para que se haga uso del servidor de Tensorflow de Seldon y el parámetro “modelUri” apuntará a la ruta donde hemos copiado nuestro modelo, en este caso en el servicio de Google Cloud Storage.

El siguiente paso será desplegar nuestro modelo a través de kubectl en el namespace “seldon” que hemos creado anteriormente. Para ello ejecutamos:

$ kubectl apply -f mnist_rest.yaml
seldondeployment.machinelearning.seldon.io/tfserving created

Tras unos segundos tendremos disponible el servicio y podremos lanzar peticiones vía REST para hacer predicciones sobre cuál es el dígito que se ha manuscrito dada una imagen.

En este notebook os dejo un ejemplo detallado de como preparar y ejecutar estas peticiones desde código Python a través de la biblioteca para peticiones HTTP requests de Python, de uso muy extendido.

Conclusión

Seldon es una herramienta tremendamente potente, que simplifica de forma notable el proceso de despliegue y gobierno de modelos de Machine Learning. Se apoya sobre toda la potencia de Kubernetes lo que lo hace una herramienta apta para el mundo empresarial. También tiene integraciones con otras herramientas muy extendidas como OpenShift, Kubeflow, Prometheus para métricas o Jaeger para trazas distribuidas.

Seldon tiene detrás una gran comunidad y una compañía que respalda su desarrollo lo que hace que esté en constante evolución. Algunas de las características más avanzadas e interesantes que se han incluido en Seldon y que quedan fuera de este artículo son las nuevas capacidades de explicabilidad de modelos o el enrutado inteligente. Seguiremos muy atentos a la evolución de Seldon profundizando en sus capacidades y ayudando a nuestros clientes a desplegar machine learning en sus compañías de forma más eficiente.

Cuéntanos qué te parece.

Enviar.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.