
¡Hola a todos! Soy desarrollador de CV en KROK. Durante 3 años hemos llevado a cabo proyectos en el campo de CV. Durante este tiempo, hemos hecho de todo, por ejemplo: monitorear a los conductores para que no beban, fumen o hablen por teléfono mientras conducen, asegurándonos de que miren la carretera y no los sueños o las nubes; registrar a quienes usan los carriles exclusivos y ocupan varios lugares de estacionamiento; supervisar que los empleados usen cascos, guantes, etc.; identificar a los empleados que quieren ingresar a un sitio; contar todo lo que se puede contar.
¿A qué voy con todo esto?
En el proceso de llevar a cabo los proyectos, hemos cometido errores, muchos errores, y algunos de esos problemas ustedes los conocen o los conocerán en el futuro.
Imaginemos la situación
Supongamos que nos hemos unido a una joven empresa “N”, cuya actividad está relacionada con ML. Estamos trabajando en un proyecto de ML (DL, CV), luego por alguna razón cambiamos de trabajo, tomamos un descanso y regresamos a nuestra neural network o a la de alguien más.
- Llega el momento de la verdad, necesitamos recordar en qué nos quedamos, qué hiperparámetros probamos y, lo más importante, a qué resultados llevaron. Puede haber muchas maneras en que diferentes personas hayan almacenado información sobre todas las ejecuciones: en la cabeza, en configuraciones, en un cuaderno, en un entorno de trabajo en la nube. He visto situaciones donde los hiperparámetros se almacenaban como líneas comentadas en el código, en fin, un verdadero despliegue de imaginación. Y ahora imagina que no has vuelto a tu proyecto, sino al proyecto de alguien que dejó la empresa y te ha dejado el código y el modelo llamado model_1.pb. Para completar el cuadro y transmitir todo el dolor, imaginemos que también eres un especialista novato.
- Sigamos adelante. Para ejecutar el código, nosotros y todos los que trabajen con él necesitamos crear un entorno. A menudo sucede que, por alguna razón, también nos dejaron en herencia ese entorno. Esto también puede convertirse en una tarea no trivial. No queremos perder tiempo en este paso, ¿verdad?
- Entrenamos un modelo (por ejemplo, un detector de automóviles). Llegamos al punto en el que se convierte en algo bastante bueno: es el momento de guardar el resultado. Lo llamaremos car_detection_v1.pb. Luego entrenamos otro: car_detection_v2.pb. Un tiempo después, nuestros colegas o nosotros mismos entrenamos una y otra vez, utilizando diferentes arquitecturas. Al final, se forma un montón de artefactos, cuya información necesitamos recopilar meticulosamente (pero, lo haremos más tarde, ya que por ahora tenemos cosas más prioritarias que hacer).
- ¡Y eso es todo! ¡Tenemos un modelo! Podemos empezar a entrenar el siguiente modelo, desarrollar la arquitectura para resolver un nuevo problema, o ¿podemos ir a tomar un té? ¿Quién se encargará del despliegue?
Identificar problemas
El trabajo en un proyecto o producto es el esfuerzo de muchas personas. Con el tiempo, la gente va y viene, hay más proyectos y los propios proyectos se vuelven más complejos. De una forma u otra, situaciones del ciclo descrito anteriormente (y no solo eso) se presentarán en diversas combinaciones de iteración a iteración. Todo esto se traduce en pérdida de tiempo, confusión, nervios, y quizás descontento por parte del cliente, y en última instancia, en dinero perdido. Aunque todos solemos tropezar con los mismos errores, creo que nadie quiere revivir estos momentos una y otra vez.

Así que hemos atravesado un ciclo de desarrollo y vemos que hay problemas que debemos resolver. Para ello, necesitamos:
- almacenar los resultados de manera conveniente;
- hacer que el proceso de incorporación de nuevos empleados sea sencillo;
- simplificar el proceso de despliegue del entorno de desarrollo;
- configurar el proceso de versionado de modelos;
- tener una forma conveniente de validar los modelos;
- encontrar una herramienta de gestión del estado de los modelos;
- encontrar una forma de entregar modelos a producción.
Parece que es necesario idear un flujo de trabajo que permita gestionar fácilmente este ciclo de vida, ¿verdad? Esta práctica se llama MLOps.
MLOps, o DevOps para machine learning, permite que los equipos de especialistas en procesamiento y análisis de datos colaboren con los especialistas de TI, y también acelera el desarrollo y despliegue de modelos mediante monitoreo, verificación y un sistema de gestión para modelos de aprendizaje automático.
Puedes , qué piensan al respecto los chicos de Google. En el artículo queda claro que MLOps es un concepto bastante amplio.

A continuación en este artículo describiré solo una parte del proceso. Para la implementación, utilizaré la herramienta MLflow, ya que es un proyecto de código abierto, su conexión requiere un poco de código y tiene integración con populares marcos de trabajo de ml. Puedes buscar en internet otras herramientas, como Kubeflow, SageMaker, Trains, etc., y posiblemente encontrar la que mejor se adapte a tus necesidades.
"Construyendo" MLOps usando la herramienta MLFlow
MLFlow es una plataforma de código abierto para gestionar el ciclo de vida de los modelos de ml ().
MLflow incluye cuatro componentes:
- MLflow Tracking aborda las cuestiones de registro de resultados y parámetros que llevaron a esos resultados;
- MLflow Project permite empaquetar código y reproducirlo en cualquier plataforma;
- MLflow Models se encarga del despliegue de modelos en producción;
- MLflow Registry permite almacenar modelos y gestionar su estado en un repositorio centralizado.
MLflow opera con dos entidades:
- una ejecución es el ciclo completo de entrenamiento, parámetros y métricas que queremos registrar;
- un experimento es el "tema" que une las ejecuciones.
Todos los pasos del ejemplo se realizan en el sistema operativo Ubuntu 18.04.
1. Desplegamos el servidor
Para que podamos gestionar fácilmente nuestro proyecto y obtener toda la información necesaria, desplegaremos un servidor. El servidor de seguimiento de MLflow tiene dos componentes principales:
- el backend store se encarga de almacenar información sobre los modelos registrados (soporta 4 bases de datos: mysql, mssql, sqlite y postgresql);
- el artifact store se encarga de almacenar artefactos (soporta 7 modalidades de almacenamiento: Amazon S3, Azure Blob Storage, Google Cloud Storage, servidor FTP, servidor SFTP, NFS, HDFS).
Como artifact store para simplificar, tomaremos un servidor sftp.
- creamos un grupo
$ sudo groupadd sftpg - agregamos un usuario y le establecemos una contraseña
$ sudo useradd -g sftpg mlflowsftp $ sudo passwd mlflowsftp - ajustamos un par de configuraciones de acceso
$ sudo mkdir -p /data/mlflowsftp/upload $ sudo chown -R root.sftpg /data/mlflowsftp $ sudo chown -R mlflowsftp.sftpg /data/mlflowsftp/upload - agregamos algunas líneas en /etc/ssh/sshd_config
Match Group sftpg ChrootDirectory /data/%u ForceCommand internal-sftp - reiniciamos el servicio
$ sudo systemctl restart sshd
Como backend store tomaremos postgresql.
$ sudo apt update
$ sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all
$ sudo apt install gcc
$ pip install psycopg2
$ sudo -u postgres -i
# Crear un nuevo usuario: mlflow_user
[postgres@user_name~]$ createuser --interactive -P
Ingrese el nombre del rol a añadir: mlflow_user
Ingrese la contraseña para el nuevo rol: mlflow
Ingrese de nuevo: mlflow
¿Debería el nuevo rol ser un superusuario? (y/n) n
¿Debería el nuevo rol poder crear bases de datos? (y/n) n
¿Debería el nuevo rol poder crear más roles nuevos? (y/n) n
# Crear la base de datos mlflow_bd propiedad de mlflow_user
$ createdb -O mlflow_user mlflow_dbPara iniciar el servidor, es necesario instalar los siguientes paquetes de python (se recomienda crear un entorno virtual separado):
pip install mlflow
pip install pysftpIniciamos nuestro servidor
$ mlflow server
--backend-store-uri postgresql://mlflow_user:mlflow@localhost/mlflow_db
--default-artifact-root sftp://mlflowsftp:mlflow@sftp_host/upload
--host server_host
--port server_port2. Añadir seguimiento
Para que los resultados de nuestros entrenamientos no se pierdan, las futuras generaciones de desarrolladores comprendan lo que realmente ocurrió, y los senior y tú puedan analizar tranquilamente el proceso de entrenamiento, es necesario añadir seguimiento. El seguimiento implica guardar los parámetros, métricas, artefactos y cualquier información adicional sobre la ejecución del entrenamiento, en este caso, en el servidor.
Como ejemplo, he creado un pequeño en Keras para la segmentación de todo lo que hay en . Para añadir seguimiento, creé el archivo mlflow_training.py.
Aquí están las líneas en las que ocurre lo más interesante:
def run(self, epochs, lr, experiment_name):
# obteniendo el id del experimento, creando un experimento en su ausencia
remote_experiment_id = self.remote_server.get_experiment_id(name=experiment_name)
# creando un "run" y obteniendo su id
remote_run_id = self.remote_server.get_run_id(remote_experiment_id)
# indicar que queremos guardar los resultados en un servidor remoto
mlflow.set_tracking_uri(self.tracking_uri)
mlflow.set_experiment(experiment_name)
with mlflow.start_run(run_id=remote_run_id, nested=False):
mlflow.keras.autolog()
self.train_pipeline.train(lr=lr, epochs=epochs)
try:
self.log_tags_and_params(remote_run_id)
except mlflow.exceptions.RestException as e:
print(e)Aquí, self.remote_server es un pequeño envoltorio sobre los métodos mlflow.tracking. MlflowClient (lo hice para conveniencia), a través del cual creo un experimento y ejecuto en el servidor. A continuación, indico a dónde deben ir los resultados de la ejecución (mlflow.set_tracking_uri(self.tracking_uri)). Conecto el registro automático mlflow.keras.autolog(). Por el momento, MLflow Tracking soporta el registro automático para TensorFlow, Keras, Gluon XGBoost, LightGBM y Spark. Si no encuentras tu marco o biblioteca, siempre puedes registrar de forma explícita. Iniciamos el entrenamiento. Registramos etiquetas y parámetros de entrada en el servidor remoto.
Un par de líneas y tú, al igual que todos los interesados, tendrás acceso a la información sobre todas las ejecuciones. ¿Genial?
3. Estructuramos el proyecto
Ahora haremos que iniciar el proyecto sea muy sencillo. Para ello, añadiremos un archivo MLproject y conda.yaml en la raíz del proyecto.
MLproject
name: flow_segmentation
conda_env: conda.yaml
entry_points:
main:
parameters:
categories: {help: 'lista de categorías del conjunto de datos coco'}
epochs: {type: int, help: 'número de épocas en el entrenamiento'}
lr: {type: float, default: 0.001, help: 'tasa de aprendizaje'}
batch_size: {type: int, default: 8}
model_name: {type: str, default: 'Unet', help: 'Unet, PSPNet, Linknet, FPN'}
backbone_name: {type: str, default: 'resnet18', help: 'ejemplo resnet18, resnet50, mobilenetv2 ...'}
tracking_uri: {type: str, help: 'la dirección del servidor'}
experiment_name: {type: str, default: 'My_experiment', help: 'nombre del experimento remoto y local'}
command: "python mlflow_training.py
--epochs={epochs}
--categories={categories}
--lr={lr}
--tracking_uri={tracking_uri}
--model_name={model_name}
--backbone_name={backbone_name}
--batch_size={batch_size}
--experiment_name={experiment_name}"El proyecto MLflow tiene varias propiedades:
- Name — el nombre de tu proyecto;
- Environment — en mi caso conda_env indica que se utiliza Anaconda para la ejecución y la descripción de las dependencias se encuentra en el archivo conda.yaml;
- Entry Points — indica qué archivos y con qué parámetros podemos ejecutar (todos los parámetros al iniciar el entrenamiento se registran automáticamente)
conda.yaml
name: flow_segmentation
channels:
- defaults
- anaconda
dependencies:
- python==3.7
- pip:
- mlflow==1.8.0
- pysftp==0.2.9
- Cython==0.29.19
- numpy==1.18.4
- pycocotools==2.0.0
- requests==2.23.0
- matplotlib==3.2.1
- segmentation-models==1.0.1
- Keras==2.3.1
- imgaug==0.4.0
- tqdm==4.46.0
- tensorflow-gpu==1.14.0Como entorno de ejecución, puedes utilizar docker; para más información, consulta .
4. Iniciar el entrenamiento
Clonamos el proyecto y accedemos al directorio del proyecto:
git clone https://github.com/simbakot/mlflow_example.git
cd mlflow_example/Para ejecutar, necesitas instalar las bibliotecas
pip install mlflow
pip install pysftpDado que en el ejemplo uso conda_env, debe estar instalada Anaconda en su computadora (aunque también se puede evitar instalando todos los paquetes necesarios por cuenta propia y ajustando los parámetros de lanzamiento).
Todos los pasos preparatorios han finalizado y podemos proceder al lanzamiento del entrenamiento. Desde la raíz del proyecto:
$ mlflow run -P epochs=10 -P categories=cat,dog -P tracking_uri=http://server_host:server_port .Después de ingresar el comando, se creará automáticamente un entorno conda y se iniciará el entrenamiento.
En el ejemplo anterior, pasé la cantidad de épocas para el entrenamiento, las categorías en las que queremos segmentar (la lista completa se puede consultar ) y la dirección de nuestro servidor remoto.
La lista completa de parámetros posibles se puede consultar en el archivo MLproject.
5. Evaluamos los resultados del entrenamiento
Después de finalizar el entrenamiento, podemos acceder en el navegador a la dirección de nuestro servidor

Aquí vemos una lista de todos los experimentos (en la parte superior izquierda), así como información sobre los lanzamientos (en el medio). Podemos ver información más detallada (parámetros, métricas, artefactos y algo de información adicional) para cada lanzamiento.

Para cada métrica podemos observar el historial de cambios.

Es decir, en este momento podemos analizar los resultados de manera "manual"; también puede configurar la validación automática mediante la API de MLflow.
6. Registramos el modelo
Después de haber analizado nuestro modelo y decidir que está listo para el despliegue, procedemos a su registro. Para ello, elegimos el lanzamiento que necesitamos (como se muestra en el punto anterior) y bajamos.

Después de darle un nombre a nuestro modelo, se le asigna una versión. Al guardar otro modelo con el mismo nombre, la versión se incrementará automáticamente.

Para cada modelo, podemos agregar una descripción y seleccionar uno de los tres estados (Staging, Production, Archived); posteriormente, mediante la API podemos acceder a estos estados, lo que junto con el versionado proporciona una flexibilidad adicional.

También tenemos un acceso conveniente a todos los modelos

y sus versiones.

Como en el punto anterior, todas las operaciones se pueden realizar mediante la API.
7. Desplegamos el modelo
En esta etapa ya tenemos un modelo (keras) entrenado. Un ejemplo de cómo se puede usar:
class SegmentationModel:
def __init__(self, tracking_uri, model_name):
self.registry = RemoteRegistry(tracking_uri=tracking_uri)
self.model_name = model_name
self.model = self.build_model(model_name)
def get_latest_model(self, model_name):
registered_models = self.registry.get_registered_model(model_name)
last_model = self.registry.get_last_model(registered_models)
local_path = self.registry.download_artifact(last_model.run_id, 'model', '.\/')
return local_path
def build_model(self, model_name):
local_path = self.get_latest_model(model_name)
return mlflow.keras.load_model(local_path)
def predict(self, image):
image = self.preprocess(image)
result = self.model.predict(image)
return self.postprocess(result)
def preprocess(self, image):
image = cv2.resize(image, (256, 256))
image = image / 255.
image = np.expand_dims(image, 0)
return image
def postprocess(self, result):
return resultAquí, self.registry es nuevamente un pequeño envoltorio sobre mlflow.tracking.MlflowClient, para mayor comodidad. La idea es que accedo a un servidor remoto y busco allí un modelo con el nombre especificado, obteniendo así la versión de producción más reciente. Luego descargo el artefacto localmente en la carpeta .\/model y construyo el modelo desde este directorio con mlflow.keras.load_model(local_path). Ahora podemos usar nuestro modelo. Los desarrolladores de CV (ML) pueden continuar mejorando el modelo y publicando nuevas versiones.
En conclusión
He presentado un sistema que permite:
- almacenar de manera centralizada información sobre modelos de ML, progreso y resultados del entrenamiento;
- desplegar rápidamente un entorno de desarrollo;
- monitorear y analizar el progreso del trabajo en los modelos;
- realizar versionado y gestionar el estado de los modelos de forma cómoda;
- desplegar fácilmente los modelos obtenidos.
Este ejemplo es un juguete y sirve como punto de partida para construir su propio sistema, que puede incluir la automatización de la evaluación de resultados y el registro de modelos (puntos 5 y 6 respectivamente), o puede que agregue versionado de conjuntos de datos, o tal vez algo más. Quería transmitir la idea de que necesita MLOps en general, y MLflow es solo un medio para alcanzar el objetivo.
¿Cuáles son los problemas con los que te has encontrado que no he mostrado?
¿Qué agregarías al sistema para satisfacer tus necesidades?
¿Qué herramientas y enfoques utilizas para resolver todos o algunos de los problemas?
P.D. Dejaré un par de enlaces:
proyecto de github —
MLflow —
Mi correo electrónico de trabajo para preguntas — ikryakin@croc.ru
En nuestra empresa, se llevan a cabo regularmente diversos eventos para especialistas en TI. Por ejemplo, el 8 de julio a las 19:00 hora de Moscú, tendrá lugar un meet-up sobre CV en formato en línea. Si estás interesado, puedes participar; la inscripción está abierta. .
Fuente: habr.com
