El aprendizaje automático todavía importa
En una era de la supremacía de GPU, ¿por qué los casos comerciales del mundo real dependen tanto del aprendizaje automático clásico y la capacitación basada en CPU? La respuesta es que los datos más importantes para las aplicaciones comerciales del mundo real aún son abrumadoramente tabular, estructurado y relacional—Prea la detección de fraude, la puntuación del riesgo de seguro, la predicción de la rotación y la telemetría operativa. Resultados empíricos (por ejemplo, GrinsztaJn et al., ¿Por qué los modelos basados en árboles aún superan el aprendizaje profundo en los datos tabulares típicos? (2022), Neurips 2022 rastrea en conjuntos de datos y puntos de referencia) Muestre que para estos dominios bosque al azar, Aumento de gradientey regresión logística superan las redes neuronales tanto en precisión como en confiabilidad. También ofrecen explicación que es crítica en industrias reguladas como la banca y la atención médica.
Las GPU a menudo pierden su ventaja aquí debido a latencia de transferencia de datos (Pítico sobrecarga) y pobre escala de algunos algoritmos basados en árboles. Como consecuencia, Capacitación basada en CPU sigue siendo la opción más rentable para las cargas de trabajo de datos estructuradas en forma de pequeño en las plataformas de la nube.
En este artículo, lo guiaré a través de los pasos para la evaluación comparativa de algoritmos de aprendizaje automático tradicional en Plataforma en la nube de Google (GCP) Ofertas de CPU, incluida la Intel® Xeon® 6 Eso se hizo recientemente en general disponible. (Divulgación completa: estoy afiliado a Intel como ingeniero senior de soluciones de software de IA).
Al comparar sistemáticamente el tiempo de ejecución, la escalabilidad y el costo en los algoritmos, podemos tomar decisiones basadas en evidencia sobre qué enfoques ofrecen la mejor compensación entre precisión, velocidad y costo operativo.
Configuración de la máquina en Google Cloud
Ir a console.cloud.google.comConfigure su facturación y diríjase a “Calcule el motor”. Luego haga clic en “Crear instancia” para configurar su máquina virtual (VM). La siguiente figura muestra el Serie C4 VM Impulsado por Intel® Xeon® 6 (Nammed Ganite Rapids) y las CPU de 5th Gen Intel® Xeon® (Code-Named Emerald Rapids).
HyperThreading puede introducir la variabilidad de rendimiento porque dos hilos compiten por los recursos de ejecución del mismo núcleo. Para resultados de referencia consistentes, la configuración de “VCPU a la relación de Core” en 1 elimina esa variable, más en esto en la siguiente sección.
Antes de crear la VM, aumente el tamaño del disco de arranque del panel izquierdo: 200 GB serán más que suficientes para instalar los paquetes necesarios para este blog.
Conciencia de acceso a la memoria no uniforme (NUMA)
El acceso a la memoria no es uniforme en las CPU de múltiples núcleos y múltiples. Esto significa que la latencia y el ancho de banda de las operaciones de memoria dependen de qué núcleo de CPU está accediendo a qué región de memoria. Si no controla para NUMA, está comparando el planificador, no la CPU y los resultados pueden parecer inconsistentes. Afinidad de la memoria es exactamente lo que elimina ese problema controlando qué núcleos de CPU acceden a qué regiones de memoria. El planificador de Linux es consciente de la topología NUMA de la plataforma e intenta mejorar el rendimiento al programar hilos en procesadores que están en el mismo nodo que la memoria que se utiliza, en lugar de dejar que el programador asigne al azar funcione en todo el sistema. Sin embargo, sin controles de afinidad explícitos, no puede garantizar una colocación consistente para una evaluación comparativa confiable.
Hagamos un experimento NUMA práctico con xgboost y un conjunto de datos sintético que sea lo suficientemente grande como para estresar la memoria.
Primero, aprovisione una VM que abarque múltiples nodos NUMA, SSH en la instancia e instale las dependencias.
sudo apt update && sudo apt install -y python3-venv numactl
Luego cree y active un entorno virtual de Python para instalar scikit-learn, numpyy xgboost. Guarde el script a continuación como xgb_bench.py.
import numpy as np
import xgboost as xgb
from sklearn.datasets import make_classification
from time import time
# 10M samples, 100 features
X, y = make_classification(n_samples=10_000_000, n_features=100, random_state=42)
dtrain = xgb.DMatrix(X, label=y)
params = {
"objective": "binary:logistic",
"tree_method": "hist",
"max_depth": 8,
"nthread": 0, # use all available threads
}
start = time()
xgb.train(params, dtrain, num_boost_round=100)
print("Elapsed:", time() - start, "seconds")
A continuación, ejecute este script en tres modos (baseline / numa0 / interleave). Repita cada experimento al menos 5 veces e informe la desviación media y estándar. (¡Esto requiere otro script simple!)
# Run without NUMA binding
python3 xgb_bench.py
# Run with NUMA binding to a single node
numactl --cpunodebind=0 --membind=0 python3 xgb_bench.py
Al asignar tareas a núcleos físicos específicos, use el --physcpubind o -C opción en lugar de --cpunodebind.
# Run with interleaved memory across nodes
numactl --interleave=all python3 xgb_bench.py
¿Qué experimento tuvo la media más pequeña? ¿Qué tal la desviación estándar? Para interpretar estos números, tenga en cuenta que
- Desviación estándar más baja para
numa0indica una localidad más estable. - Media más baja para
numa0VSbaselinesugiere que el tráfico de nodos cruzados lo estaba lastimando y - Si
interleaveNarra la brecha vsbaselinesu carga de trabajo es sensible al ancho de banda y se beneficia de la difusión de páginas, a costo potencial de latencia.
Si ninguno de estos se aplica a un punto de referencia, la carga de trabajo puede estar unida al cómputo (por ejemplo, árboles poco profundos, un conjunto de datos pequeño), o la VM podría exponer un solo nodo NUMA.
Elegir los puntos de referencia correctos
Al evaluar los algoritmos de aprendizaje automático clásico en las CPU, debe construir su propio marco de prueba o aprovechar las suites de referencia existentes, o usar un enfoque híbrido si corresponde.
Suites de prueba existentes como scikit-learn_bench y Phoronix Test Suite (PTS) son útiles cuando necesita resultados estandarizados y reproducibles con los que otros pueden validar y comparar. Funcionan particularmente bien si está evaluando algoritmos bien establecidos como el bosque aleatorio, SVM o XGBOost donde los conjuntos de datos estándar proporcionan ideas significativas. Los puntos de referencia personalizados se destacan para revelar características de rendimiento específicas de implementación. Por ejemplo, pueden medir cómo los diferentes formatos de matriz dispersa afectan los tiempos de entrenamiento SVM, o cómo el preprocesamiento de las tuberías impactan el rendimiento general en su arquitectura de CPU específica. Los conjuntos de datos que utiliza influyen directamente en lo que revela su punto de referencia. No dude en consultar al oficial puntos de referencia de Scikit-Learn por inspiración. Aquí también hay un conjunto de muestras que puede usar para crear una prueba personalizada.
| Conjunto de datos | Tamaño | Tarea | Fuente |
| Higgs | 11m filas | Clasificación binaria | UCI ML Repo |
| Retraso de la aerolínea | Variable | Clasificación múltiple | Bts |
| Vivienda de California | 20k filas | Regresión | sklearn.datasets.fetch_california_housing |
| Sintético | Variable | Pruebas de escala | sklearn.datasets.make_classification |
Los conjuntos de datos de escala sintética son especialmente útiles para exponer diferencias en el caché, el ancho de banda de memoria y la E/S.
En el resto de este blog, ilustramos cómo puede ejecutar experimentos utilizando el código abierto scikit-learn_bench que actualmente admite marcos Scikit-Learn, Cuml y XGBOost.
Instalaciones y evaluación comparativa
Una vez que se inicializa la VM GCP, puede SSH en la instancia y ejecutar los comandos a continuación en su terminal.
sudo apt update && sudo apt upgrade -y
sudo apt install -y git wget numactl
Para instalar Conda en una VM GCP, deberá contabilizar la arquitectura de la CPU. Si no está seguro sobre la arquitectura de su VM, puede ejecutar
uname -m
antes de proceder a
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh
# Use the installer for Linux aarch64 if your VM is based on Arm architecture.
# wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh -O ~/miniconda.sh
A continuación, debe ejecutar el script y aceptar los Términos de servicio (TOS).
bash ~/miniconda.sh
source ~/.bashrc
Finalmente, clone el último scikit-learn_bench de Github, cree un entorno virtual e instale las bibliotecas de Python requeridas.
git clone https://github.com/IntelPython/scikit-learn_bench.git
cd scikit-learn_bench
conda env create -n sklearn_bench -f envs/conda-env-sklearn.yml
conda activate sklearn_bench
En este punto, debería poder ejecutar un punto de referencia utilizando el módulo sklbench y una configuración específica:
python -m sklbench --config configs/xgboost_example.json
Por defecto, Sklbench compare tanto las implementaciones estándar de Scikit-Learn como sus contrapartes optimizadas proporcionadas por sklearnex (Extensión acelerada de Intel) o otros marcos compatibles como Cuml o Xgboost, y registra los resultados junto con metadatos de hardware y software en result.json. Puede personalizar el archivo de salida con --result-filee incluir --report para producir un informe de Excel (report.xlsx). Para obtener una lista de todas las opciones compatibles, consulte el documentación.
Como se discutió anteriormente, puede usar numactl para fijar un proceso y sus procesos infantiles a núcleos de CPU específicos. Aquí está cómo correr sklbench con numactlvinculándolo a los núcleos seleccionados:
cores="0-3"
export runid="$(date +%Y%m%d%H%M%S)"
numactl --physcpubind $cores python3 -m sklbench \
--config configs/regular \
--filters algorithm:library=sklearnex algorithm:device=cpu algorithm:estimator=RandomForestClassifier \
--result-file $result-${runid}.json
Interpretar resultados y mejores prácticas
El generador de informes Le permite combinar los archivos de resultados de múltiples ejecuciones.
python -m sklbench.report --result-files <result 1> <result 2>
La verdadera métrica para la toma de decisiones en la nube es el costo por tarea, a saber,
Costo por tarea = tiempo de ejecución en horas x precio por hora.
Las implementaciones del mundo real rara vez se comportan como un solo punto de referencia. Para modelar con precisión el costo por tarea, es útil tener en cuenta el comportamiento de impulso de CPU, la variabilidad de la infraestructura en la nube y la topología de la memoria, ya que todos pueden influir en el rendimiento de formas que no se capturan mediante una medición única. Para reflejar mejor las características reales de tiempo de ejecución, recomiendo comenzar con iteraciones de calentamiento para estabilizar la escala de frecuencia de CPU. Luego ejecute cada experimento varias veces para tener en cuenta el ruido del sistema y los efectos transitorios. Informar la desviación media y estándar ayuda a la superficie de las tendencias consistentes, mientras que el uso de medianas puede ser más robusta cuando la varianza es alta, especialmente en entornos de nubes donde los vecinos ruidosos o la contención de recursos pueden sesgar promedios. Para la reproducibilidad, es importante corregir versiones de paquetes y usar instantáneas consistentes de imagen VM. La inclusión de la configuración de NUMA en sus resultados ayuda a otros a comprender los efectos de la localidad de la memoria, lo que puede afectar significativamente el rendimiento. Herramientas como Scikit-Learn_bench automatizan muchos de estos pasos, lo que hace que sea más fácil producir puntos de referencia que sean representativos y repetibles.
Si encontró este artículo valioso, considere compartirlo con su red. Para obtener más contenido sobre cómo hacer un desarrollo de IA, visite Recursos de desarrollo de IA Intel®.
Expresiones de gratitud
El autor agradece a Neal Dixon, Miriam Gonzales, Chris Liebert y Rachel Novak por proporcionar comentarios sobre un borrador anterior de este trabajo.
Recursos