Entrenamiento y despliegue de modelos con BaseModelService

Disponible en versión 1.4 de cliente Python

En esta guía se explica paso a paso cómo entrenar y ejecutar un modelo de sentiment analysis en una instancia de la Onesait Platform (en adelante OSP) mediante BaseModelService. La guía asume que se va a usar la instancia de OSP deplegada en https://lab.onesaitplatform.com. Será necesario registrarse siguiendo las instrucciones del enlace sign up si no se hubiese hecho antes y hacer login en la aplicación.

El modelo de sentiment análisis se entrenará a partir del este pequeño dataset. El dataset es una pequeña selección del siguiente dataset. Será un clasificador binario que asignará un valor 1 a los textos con sentiment positivo y 0 a los textos con sentiment negativo.

¿Qué es BaseModelService?

BaseModelService es una clase Python que se distribuye como parte del cliente de Python para OSP. El código de este cliente lo mantiene la comunidad de OSP en Github y puede ser instalado mediante pip:

 

pip install onesaitplatform-client-services

 

BaseModelService permite:

  • Entrenar modelos.

  • Reentrenar modelos para generar nuevas versiones de estos.

  • Desplegar los modelos entrenados.

  • Hacer inferencia con los modelos desplegados.

Todo ello se hace aprovechando las herramientas que OSP proporciona para:

  • La gestión de los datasets de entrenamiento.

  • El almacenaje de los modelos entrenados.

  • El control de sus distintas versiones.

  • El despliegue mediante microservicios.

BaseModelService abstrae al desarrollador del modelo la gestión de toda esta funcionalidad, permitiéndole hacer uso de ella de una manera sencilla. Como sugiere su nombre, BaseModelService es una clase madre a partir de la cual el desarrollador del modelo creará una clase hija que herede de ella.

La clase hija contendrá el código específico para entrenar un modelo concreto, guardarlo en una ruta local, cargar posteriormente la versión guardada también desde una ruta local y usarlo en inferencia. El desarrollador del modelo podrá usar cualquier tipo de librería de Python (scikit-learn, Tensorflow, PyTorch, etc.). Podrá también usar los mecanismos de guardado y carga de modelo que prefiera.

El resto de tareas de interacción con OSP ya han sido definidas en la clase madre BaseModelService: descarga del dataset desde un archivo del File Repository, o desde una ontología; guardado de los modelos entrenados en el File Repository, descarga de estos modelos desde dicho File Repository, control de las distintas versiones de un mismo modelo y selección de la versión preferida.

¿Qué hace falta tener en OSP?

OSP proporciona el soporte para la gestión y almacenaje de datasets y modelos. Para ello, hace falta configurar lo siguiente:

  • Un dataset en el File Repository. Será el dataset que se utilizará para entrenar el modelo.

  • Alternativamente, una ontología en la que se guarde el dataset en cuestión.

  • Una ontología en la que se registren las distintas versiones del modelo.

  • Un Digital Client al que se asocien las ontologías anteriores y permita el acceso a ellas.

Subir un dataset al File Repository

En primer lugar, se subirá el dataset de entrenamiento del modelo de sentiment analysis al File Repository de nuestra instancia de OSP. El dataset en cuestión puede descárguese aquí. Asumiendo que se tiene el fichero descargado en una dirección local, se puede usar el siguiente código para subirlo al File Repository:

 

import json from onesaitplatform.files import FileManager HOST = "www.lab.onesaitplatform.com" USER_TOKEN = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcmluY2lwYWwiOiJianJhbWlyZXoiLCJjbGllbnRJZCI6Im9uZXNhaXRwbGF0Zm9ybSIsInVzZXJfbmFtZSI6ImJqcmFtaXJleiIsInNjb3BlIjpbIm9wZW5pZCJdLCJuYW1lIjoiYmpyYW1pcmV6IiwiZXhwIjoxNjE3ODI2NjkzLCJncmFudFR5cGUiOiJwYXNzd29yZCIsInBhcmFtZXRlcnMiOnsidmVydGljYWwiOm51bGwsImdyYW50X3R5cGUiOiJwYXNzd29yZCIsInVzZXJuYW1lIjoiYmpyYW1pcmV6In0sImF1dGhvcml0aWVzIjpbIlJPTEVfREFUQVNDSUVOVElTVCJdLCJqdGkiOiJmNGM2NDUzZC0xYTEyLTRkMGUtYTVlNy05ZmNlMDY4OTY1NDYiLCJjbGllbnRfaWQiOiJvbmVzYWl0cGxhdGZvcm0ifQ.Nz5cDvMjh361z4r6MMD2jUOpYSmUKVLkMThHDK0sg6o" file_manager = FileManager(host=HOST, user_token=USER_TOKEN) file_manager.protocol = "https" uploaded, info = file_manager.upload_file("sentiment_analysis_dataset.csv", "./sentiment_analysis_dataset.csv") print("Uploaded file: {}".format(uploaded)) print("Information: {}".format(info))

 

Nótese que se usa para hacer la subida el cliente de Python a la OSP. Puede consultarse la documentación correspondiente aquí. Para la autenticación ha de usarse el token de usuario que se proporciona en el panel de control de la OSP. Puede encontrarse pinchando en APIs en la esquina superior derecha del panel de control. Es un token temporal que tendrá una duración limitada.

 

En la respuesta del código utilizado arriba se pintará el identificador que el File Repository ha asignado al fichero subido. Este identificador habrá que proporcionarlo después para lanzar el entrenamiento del modelo a partir de este dataset.

Crear una ontología para el registro de versiones del modelo

A continuación se creará una ontología que se llamará SentimentAnalysisModels, necesaria para llevar el registro de las versiones del modelo que se vayan entrenando. Para la creación de la ontología se debe usar el menú de la margen izquierda del panel de control: Development > My Ontologies.

 

En la margen superior derecha de la pantalla resultante se pincha en CREATE.

Y en la siguiente pantalla se pincha en Creation Step by Step.

Se abre como resultado el formulario para la creación de la ontología. Se cumplimentan los datos obligatorios (NAME, DESCRIPTION y META-INFORMATION). Como se ha dicho, NAME será SentimentAnalysisModels:

En la sección inferior de la misma pantalla, se selecciona la template de ontología GENERAL:

Y dentro de GENERAL, se pincha en la última opción, EMPTY BASE:

Esto habilitará en la misma pantalla lo siguiente:

Pínchese en UPDATE SCHEMA. Esto abrirá un editor como el siguiente:

Cámbiese el modo de Tree a Text y cámbiese el contenido por el siguiente esquema:

 

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "SentimentAnalysisModels", "type": "object", "required": [ "SentimentAnalysisModels" ], "properties": { "SentimentAnalysisModels": { "type": "string", "$ref": "#/datos" } }, "datos": { "description": "Info SentimentAnalysisModels", "type": "object", "required": [ "name", "description", "asset", "version", "metrics", "hyperparameters", "model_path", "date", "active" ], "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "asset": { "type": "string" }, "version": { "type": "string" }, "metrics": { "type": "array", "items": { "type": "object", "required": [ "name", "value" ], "properties": { "name": { "type": "string" }, "value": { "type": "string" }, "dtype": { "type": "string" } }, "additionalProperties": false }, "minItems": 0 }, "hyperparameters": { "type": "array", "items": { "type": "object", "required": [ "name", "value" ], "properties": { "name": { "type": "string" }, "value": { "type": "string" }, "dtype": { "type": "string" } }, "additionalProperties": false }, "minItems": 0 }, "model_path": { "type": "string" }, "date": { "type": "string", "format": "date-time" }, "dataset_path": { "type": "string" }, "active": { "type": "boolean" }, "ontology_dataset": { "type": "string" } } }, "description": "Definition of trained models", "additionalProperties": true }

Una vez efectuado el cambio, en la margen inferior derecha de la pantalla, se procede a la creación de la ontología pinchando en NEW:

Con ello, se ha creado la ontología para el registro de las distintas versiones del modelo de sentiment analysis que se vayan creando. Los campos de la ontología, como se ve arriba, son los siguientes:

  • name: nombre del modelo.

  • description: descripción del modelo.

  • asset: nombre del activo en el cual se encuadra el modelo.

  • version: versión del modelo.

  • metrics: lista de criterios de evaluación del modelo. Cada criterio de la lista consta de un campo name, nombre del criterio; un campo value, valor para ese criterio; y dtype, tipo de dato del valor.

  • hyperparameters: lista de hiperparámetros con los cuales se ha entrenado el modelo (cada hiperparámetro de la lista consta de un campo name, nombre del hiperparámetro; otro value, valor del hiperparámetro; y dtype, tipo de dato del valor).

  • model_path: identificador del fichero correspondiente al modelo guardado en File Repository

  • date: fecha y hora en la que se crea el modelo.

  • dataset_path: identificador del fichero correspondiente al dataset de entrenamiento utilizado para el entrenamiento en File Repository.

  • active: booleano que denota si una versión del modelo está activa. Normalmente, solo una versión del modelo estará activa, y será esta la que se carga como modelo servicializado.

  • ontology_dataset: nombre de la ontología en la que se ha guardado el dataset.

Creación de un Digital Client

Una vez se tiene una ontología SentimentAnalysisModels, ha de crearse un Digital Client con el que BaseModelService pueda acceder a la ontología en cuestión. Para ello, pínchese en el menú de la margen izquierda del panel de control en Clients & Digital Twins > My Digital Clients:

De nuevo pínchese en CREATE en la pantalla resultante:

Con ello se accede al formulario de creación del Digital Client. Se ha de rellenar el campo IDENTIFICATION con el nombre SentimentAnalysisDigitalClient y se ha de añadir una descripción en DESCRIPTION. En ONTOLOGIES se selecciona la ontología creada anteriormente (SentimentAnalysisModels) y se le da ACCESS LEVEL ALL. Se pincha en ADD ONTOLOGY:

Téngase en cuanta que el token que aparece bajo este formulario será necesario en adelante para acceder a la ontología a través de este Digital Client. Para que la creación del Digital Client sea efectiva se ha de pinchar en el botón NEW que se muestra en la margen inferior derecha de esta pantalla:

Con ello se ha creado el Digital Client SentimentAnalysisDigitalClient que se usará para acceder a la ontología de registro de versiones del modelo.

Creación de una clase hija de BaseModelService: SentimentAnalysisModelService

Para crear un objeto que gestione el entrenamiento, guardado, carga, despliegue y uso de un modelo concreto, se ha de crear una clase de Python que herede de BaseModelService. En este tutorial se va a crear una clase que gestione modelos de sentiment analysis. Se le llamará, entonces, SentimentAnalysisModelService:

 

 

Como se ve arriba, la clase hija ha de sobrescribir los métodos init, load_model, train y predict de BaseModelService.

El código lo vamos a colocar y ejecutar en un Notebook en nuestra instancia de la OSP en https://lab.onesaitplatform.com. Para ello, en el formulario de la margen izquierda del panel de control se ha de pinchar en MY ANALYTICS TOOLS > MY NOTEBOOKS.

Con ello, se abre una pantalla en cuya esquina superior derecha se debe pinchar en NEW NOTEBOOK:

Esto abre un formulario en el que se puede dar nombre al notebook:

Una vez se da a OK, se abre un notebook de Apache Zeppelin en el cual se va a escribir el código que sigue a continuación.

En concreto, se va a crear una clase SentimentAnalysisModelService que gestione modelos de sentiment analysis sobre datos del español. Será un clasificador binario de texto: el output será 0 para textos con sentiment negativo, 1 para los textos con sentiment positivo. Se va a usar para ello Tensorflow 2.x. Se construirá un perceptrón cuyo input será un bag of words con tf-idf. Serán modelos de juguete. No se pretende elaborar buenos modelos, solo mostrar cómo desarrollarlos de manera sencilla. El guardado del modelo se hará mediante h5 y pickle: un fichero con los pesos resultantes del entrenamiento y otro fichero para el tokenizador que se entrena para hacer el preprocesamiento del texto.

Se importan, entonces, las librerías y clases necesarias para construir el modelo tal y como se ha descrito. Junto a ellas, se importa la clase BaseModelService:

 

 

Sobrescribir el método init

En el método init se inicializarán los atributos que después se utilizarán en otros métodos para hacer referencia al modelo. En concreto, para el modelo de sentiment que se va a desarrollar en este tutorial, se van a habilitar dos atributos: uno en el que se guardará el modelo mismo (model), la red neuronal que devolverá 1 para textos de sentiment positivo y 0 para textos con sentiment negativo; y otro para el preprocesador de texto (preprocessor):

 

 

Sobrescribir el método load_model

El método load_model es el encargado de construir el modelo que va a servicializarse a partir del archivo o archivos en los que este haya sido previamente guardado. Este método se ejecuta en el momento en el que se crea el objeto. El constructor del objeto buscará en la ontología correspondiente de OSP el modelo adecuado y lo descargará, desde el File Repository de OSP, a un directorio local. Esta descarga contendrá exactamente los ficheros y/o directorios que hayan sido creados en el momento en el que se guardó el modelo (ver método train).

Al método load_model se le pasan estos dos parámetros:

  • model_path: es la ruta del directorio local donde se ubican los ficheros y/o directorios necesarios para cargar el modelo. El desarrollador asume que en esa ruta encontrará todos los ficheros y/o directorios que creó en el momento en el que guardó el modelo que ahora se pretende cargar. Por tanto, podrá ahora reconstruir el modelo a partir de dichos elementos.

  • hyperparameters: es un diccionario con todos los hyperparámetros que se usaron para entrenar el modelo. Pudieran ser necesarios para su reconstrucción. En este ejemplo no se utilizarán.

En concreto, para la clase SentimentAnalysisModelService se asume que los modelos se guardan en dos archivos: un h5 con la red neuronal de Tensorflow y un pickle con el objeto tokenizador que preprocesa el texto. Por tanto, se asume que estos dos archivos han de ser proporcionados dentro del directorio model_path:

  • model.h5

  • tokenizer.pkl

La red neuronal se guarda en el atributo model, mientras que el tokenizador se guarda en el atributo preprocessor (ambos previamente inicializados en el método init). Véase el código:

 

Sobrescribir el método train

El método train es el encargado de entrenar el modelo. Se ejecuta internamente cuando el desarrollador ejecuta uno de estos métodos, implementados en BaseModelService:

  • train_from_file_system: lanza el entrenamiento de un modelo a partir de un dataset previemente guardado en el File Repository de OSP.

  • train_from_ontology: lanza el entrenamiento de un modelo a partir de un dataset guardado en una ontología de OSP.

El método train recibe los siguientes parámetros:

  • dataset_path: es la ruta local al fichero en el que se provee el dataset de entrenamiento. Este fichero puede tener su origen en un fichero previamente guardado en el File Repository. En tal caso, tendrá exactamente el formato del fichero guardado. Si el origen del fichero fuera una ontología, esta se habrá convertido a un CSV con “,” como delimitador y tantas columnas como campos tengan los registros de la ontología.

  • hyperparameters: es un diccionario con los hiperparámetros que se le pasaron a los métodos train_from_file_system o train_from_ontology en el momento de lanzar el entrenamiento.

  • model_path: es la ruta al directorio local en el que hay que guardar los ficheros o directorios en los cuales se va a salvar el modelo una vez entrenado.

El desarrollador tendrá que leer el dataset desde el fichero local proporcionado en dataset_path. Con ello, alimentará el proceso de entrenamiento. Una vez terminado éste, tendrá que guardar el modelo resultante en el directorio indicado en model_path. Además, el método train tiene que devolver un diccionario con las métricas de evaluación del modelo que el desarrollador considere necesarias.

En el caso de SentimentAnalysisModelTrain, se asumirá que el dataset de entrenamiento es un CSV con “,” como delimitador. Este dataset contendrá dos columnas:

  • text: con los textos que contienen las opiniones.

  • label: con un 1 para textos con opinión positiva y un 0 para los de opinión negativa.

Entrenamos un modelo con Tensorflow2.x. Para el preprocesamiento de los textos usamos el tokenizador de Keras que convierte cada texto a un vector de n posiciones que representa un bag of words con tf-idf: cada posición del vector denota una palabra (siempre la misma) con un valor numérico (entre 0 y 1) que denota lo relevante que esa palabra es en el texto en cuestión. Véase el código:

 

Sobrescribir el método predict

El método predict recibe un parámetro (input) con la lista de inputs para los que se ha de hacer inferencia; calcula el output conforme al modelo, y lo devuelve en una lista. En concreto, para SentimentAnalysisModelService, se asume que el input es una lista de textos. Se tomarán, por un lado el modelo del atributo model, y por otro el preprocesador de texto del atributo preprocessor (ambos inicializados en init e instanciados en load_model) y con ellos se procesa el input. Se devuelven los resultados.

 

Crear un objeto, entrenar y predecir

Se asume que han sido creados los siguientes elementos en el despliegue de OSP de https://lab.onesaitplatform.com/:

  • Un dataset como archivo CSV con “,” como separador en el File Repository. El dataset tendrá dos columnas: text (con los textos) y label (con valor 1 o 0, donde 1 denota que el texto tiene sentiment positivo y 0 denota que el texto tiene sentiment negativo).

  • Una ontología llamada SentimentAnalysisModels con la estructura mostrada arriba.

  • Un Digital Client asociado a la ontología anterior, llamado SentimentAnalysisDigitalClient.

  • La clase SentimentAnalisisModelService descrita arriba.

Con todo ello, se va a crear el objeto sentiment_analysis_model_service de clase SentimentAnalisisModelService:

 

 

Los parámetros que se le pasan al objeto son los siguientes:

  • PLATFORM_HOST: Host del despliegue de OSP en el que se va a trabajar. En este caso, lab.onesaitplatform.com.

  • PLATFORM_PORT: Puerto en el que está servida la OSP.

  • PLATFORM_DIGITAL_CLIENT: Nombre del Digital Client creado en OSP para dar acceso a las ontologías.

  • PLATFORM_DIGITAL_CLIENT_TOKEN: Token de autenticación correspondiente al Digital Client.

  • PLATFORM_DIGITAL_CLIENT_PROTOCOL: Protocolo bajo el cual se establecerán la comunicaciones con OSP.

  • PLATFORM_DIGITAL_CLIENT_AVOID_SSL_CERTIFICATE: Verdadero si se pretende establecer las conexiones sin certificado.

  • PLATFORM_ONTOLOGY_MODELS: Nombre de la ontología en la que se registrarán las distintas versiones del modelo creadas.

  • PLATFORM_USER_TOKEN: Token de autenticación de un usuario de OSP.

  • TMP_FOLDER: Directorio local que se utilizará como dirección local a la cual se descargarán temporalmente los elementos del File Repository de OSL; y en el cual se guardarán temporalmente los modelos antes de ser subidos al File Repository.

  • NAME: Nombre del model service.

Una vez se ha creado el objeto sentiment_analysis_model_service, este está dispuesto para entrenar versiones del modelo de sentiment analysis tal como se definió en la clase SentimentAnalysisModelService. Además, en el momento de crearse el objeto, si la ontología de OSP referenciada en PLATFORM_ONTOLOGY_MODELS contiene ya algún modelo en estado activo (active True), este se cargará en memoria y estará dispuesto para su uso mediante el método predict.

Para entrenar una versión del modelo, se puede ejecutar uno de estos dos métodos:

  • train_from_file_system: lanza el entrenamiento de un modelo a partir de un dataset previemente guardado en el File Repository de OSP.

  • train_from_ontology: lanza el entrenamiento de un modelo a partir de un dataset guardado en una ontología de OSP.

En el siguiente código se lanza el entrenamiento de un modelo a partir de un dataset previamente subido al File Repository de OSP:

 

 

Nótese que el valor de DATASET_FILE_ID es el identificador del fichero que contiene el dataset en el File Repository de OSP.

Una vez se ha entrenado con éxito una versión del modelo, esta será guardada en el File Repository de OSP, y será registrada en la ontología SentimentAnalysisModels. Téngase en cuenta que las versiones de los modelos se guardan como active False. Habrá que activar una de las versiones para que esta se disponibilice al crear un nuevo objeto SentimentAnalysisModelService.

Una vez existe una versión activa del modelo en SentimentAnalysisModels, al crearse una nueva instancia de SentimentAnalysisModelService, esta tendrá dicho modelo cargado y disponible para usarse en inferencia mediante el método process:

 

Activación del modelo preferido mediante Query Tool

Como se explica arriba, el proceso de entrenamiento registra el modelo entrenado, en este caso en la ontología SentimentAnalysisModels. De entrada, el registro queda como active False. El modelo que se carga para inferencia es el único registro en SentimentAnalysisModels que está registrado como active True. Para gestionar la versión del modelo que está activo en cada momento se puede usar la herramienta Query Tool de OSP. A esta herramienta se accede desde el panel de control, en el menú del margen izquierdo:

Nos aparecerá el formulario mediante el cual tenemos que seleccionar nuestra ontología SentimentAnalysisModels:

Una vez seleccionada la ontología, se abre una herramienta que permite hacer consultas SQL a la ontología. Esta herramienta permite observar las versiones del modelo disponibles y actualizar uno de ellos como active True.

Una vez la versión del modelo deseada es active True, al crear un objeto SentimentAnalysisModelService nuevo, éste cargará en memoria dicha versión del modelo, con lo cual ésta estará disponible para hacer inferencia mediante el método predict.