Resultados de las pruebas
Se utilizaron los scripts TeraSort y TeraValidate en la herramienta de prueba de rendimiento TeraGen para medir la validación del rendimiento de Spark con las configuraciones E5760, E5724 y AFF-A800. Además se probaron tres casos de uso principales: Las canalizaciones SPARK NLP y el entrenamiento distribuido TensorFlow, el entrenamiento distribuido Horovod y el aprendizaje profundo multi-trabajador usando Keras para la predicción de CTR con DeepFM.
Para la validación E-Series y StorageGRID, utilizamos el factor de replicación de Hadoop 2. Para la validación AFF, solo utilizamos una fuente de datos.
En la siguiente tabla se enumera la configuración de hardware para la validación del rendimiento de Spark.
Tipo | Nodos de trabajo de Hadoop | Tipo de unidad | Unidades por nodo | Controladora de almacenamiento |
---|---|---|---|---|
SG6060 |
4 |
SAS |
12 |
Un único par de alta disponibilidad |
E5760 |
4 |
SAS |
60 |
Un único par de alta disponibilidad |
E5724 |
4 |
SAS |
24 |
Un único par de alta disponibilidad |
AFF800 |
4 |
SSD |
6 |
Un único par de alta disponibilidad |
En la siguiente tabla se enumeran los requisitos de software.
De NetApp | Versión |
---|---|
RHEL |
7.9 |
Entorno de ejecución de OpenJDK |
1.8.0 |
Servidor OpenJDK VM de 64 bits |
25.302 |
Git |
2.24.1 |
GCC/G++ |
11.2.1 |
Chispa |
3.2.1 |
PySpark |
3.1.2 |
SparkNLP |
3.4.2 |
TensorFlow |
2.9.0 |
Keras |
2.9.0 |
Horovod |
0.24.3 |
Análisis de la confianza financiera
Publicamos "TR-4910: Análisis de sentimiento en las comunicaciones de los clientes con IA de NetApp", En el que se ha creado una canalización de IA conversacional integral con el "Kit de herramientas de operaciones de datos de NetApp", Almacenamiento AFF y NVIDIA DGX System. La canalización realiza el procesamiento de señales de audio por lotes, el reconocimiento automático de voz (ASR), el aprendizaje de transferencia y el análisis de sentimiento con el conjunto de herramientas DataOPS, "SDK de NVIDIA Riva", y la "Marco Tao". Ampliando el caso de uso del análisis de sentimiento al sector de los servicios financieros, construimos un flujo de trabajo SparkNLP, cargamos tres modelos BERT para diversas tareas de NLP, como el reconocimiento de entidades con nombre, y obtuvimos un sentimiento a nivel de frase para las llamadas trimestrales de beneficios de las empresas incluidas en el NASDAQ Top 10.
El siguiente script sentiment_analysis_spark. py
Utiliza el modelo FinBERT para procesar transcripciones en HDFS y producir recuentos de sentimientos positivos, neutros y negativos, como se muestra en la siguiente tabla:
-bash-4.2$ time ~/anaconda3/bin/spark-submit --packages com.johnsnowlabs.nlp:spark-nlp_2.12:3.4.3 --master yarn --executor-memory 5g --executor-cores 1 --num-executors 160 --conf spark.driver.extraJavaOptions="-Xss10m -XX:MaxPermSize=1024M" --conf spark.executor.extraJavaOptions="-Xss10m -XX:MaxPermSize=512M" /sparkusecase/tr-4570-nlp/sentiment_analysis_spark.py hdfs:///data1/Transcripts/ > ./sentiment_analysis_hdfs.log 2>&1 real13m14.300s user557m11.319s sys4m47.676s
En la tabla siguiente se enumera el análisis del sentimiento de «llamada a los beneficios» a nivel de frase de las empresas NASDAQ Top 10 de 2016 a 2020.
Recuentos de confianza y porcentaje | Todas las 10 empresas | AAPL | AIRBUS | AMZN | CSCO | GOOGL | INTC | MSFT | NVDA |
---|---|---|---|---|---|---|---|---|---|
Recuentos positivos |
7447 |
1567 |
743 |
290 |
682 |
826 |
824 |
904 |
417 |
Recuentos de punto muerto |
64067 |
6856 |
7596 |
5086 |
6650 |
5914 |
6099 |
5715 |
6189 |
Recuentos negativos |
1787 |
253 |
213 |
84 |
189 |
97 |
282 |
202 |
89 |
Conteos sin categorizar |
196 |
0 |
0 |
76 |
0 |
0 |
0 |
1 |
0 |
(recuentos totales) |
73497 |
8676 |
8552 |
5536 |
7521 |
6837 |
7205 |
6822 |
6695 |
En términos de porcentajes, la mayoría de las sentencias pronunciadas por los CEOs y CFO son fácticas y, por lo tanto, tienen un sentimiento neutral. Durante una llamada de beneficios, los analistas hacen preguntas que podrían transmitir un sentimiento positivo o negativo. Vale la pena investigar cuantitativamente cómo la confianza negativa o positiva afecta los precios de las acciones el mismo día o día siguiente de las operaciones.
En la siguiente tabla se enumera el análisis de sentimiento a nivel de frase para las empresas NASDAQ Top 10, expresado en porcentaje.
Porcentaje de confianza | Todas las 10 empresas | AAPL | AIRBUS | AMZN | CSCO | GOOGL | INTC | MSFT | NVDA |
---|---|---|---|---|---|---|---|---|---|
Positivo |
10.13 % |
18.06 % |
8.69 % |
5.24 % |
9.07 % |
12.08 % |
11.44 % |
13.25 % |
6.23 % |
Neutro |
87.17 % |
79.02 % |
88.82 % |
91.87 % |
88.42 % |
86.50 % |
84.65 % |
83.77 % |
92.44 % |
Negativo |
2.43 % |
2.92 % |
2.49 % |
1.52 % |
2.51 % |
1.42 % |
3.91 % |
2.96 % |
1.33 % |
Sin clasificar |
0.27 % |
0 % |
0 % |
1.37 % |
0 % |
0 % |
0 % |
0.01 % |
0 % |
En cuanto al tiempo de ejecución del flujo de trabajo, observamos una mejora significativa de 4.78x con respecto a local
Mode a un entorno distribuido en HDFS y una mejora adicional del 0.14 % gracias al aprovechamiento de NFS.
-bash-4.2$ time ~/anaconda3/bin/spark-submit --packages com.johnsnowlabs.nlp:spark-nlp_2.12:3.4.3 --master yarn --executor-memory 5g --executor-cores 1 --num-executors 160 --conf spark.driver.extraJavaOptions="-Xss10m -XX:MaxPermSize=1024M" --conf spark.executor.extraJavaOptions="-Xss10m -XX:MaxPermSize=512M" /sparkusecase/tr-4570-nlp/sentiment_analysis_spark.py file:///sparkdemo/sparknlp/Transcripts/ > ./sentiment_analysis_nfs.log 2>&1 real13m13.149s user537m50.148s sys4m46.173s
Como se muestra en la siguiente figura, el paralelismo de datos y modelos mejoró el procesamiento de datos y la velocidad de inferencia del modelo TensorFlow distribuido. La ubicación de los datos en NFS produjo un tiempo de ejecución ligeramente mejor porque el cuello de botella del flujo de trabajo es la descarga de modelos preentrenados. Si aumentamos el tamaño de los conjuntos de datos de transcripciones, la ventaja de NFS es más evidente.
Distribuye la formación con el rendimiento de Horovod
El siguiente comando produjo información de tiempo de ejecución y un archivo de registro en nuestro clúster de Spark mediante una sola master
nodo con 160 ejecutores cada uno con un núcleo. La memoria del ejecutor estaba limitada a 5 GB para evitar errores de memoria insuficiente. Consulte la sección "“Guiones de Python para cada caso de uso principal”" para obtener más información sobre el procesamiento de datos, el entrenamiento de modelos y el cálculo de precisión de modelos en keras_spark_horovod_rossmann_estimator.py
.
(base) [root@n138 horovod]# time spark-submit --master local --executor-memory 5g --executor-cores 1 --num-executors 160 /sparkusecase/horovod/keras_spark_horovod_rossmann_estimator.py --epochs 10 --data-dir file:///sparkusecase/horovod --local-submission-csv /tmp/submission_0.csv --local-checkpoint-file /tmp/checkpoint/ > /tmp/keras_spark_horovod_rossmann_estimator_local. log 2>&1
El tiempo de ejecución resultante con diez épocas de entrenamiento fue el siguiente:
real43m34.608s user12m22.057s sys2m30.127s
Se necesitaron más de 43 minutos para procesar datos de entrada, entrenar un modelo DNN, calcular la precisión y generar puntos de control TensorFlow y un archivo CSV para resultados de predicción. Limitamos el número de épocas de entrenamiento a 10, que en la práctica a menudo se establece a 100 para garantizar una precisión satisfactoria del modelo. El tiempo de entrenamiento se escala linealmente con el número de épocas.
A continuación, utilizamos los cuatro nodos de trabajo disponibles en el clúster y ejecutamos el mismo script en yarn
Modo con datos en HDFS:
(base) [root@n138 horovod]# time spark-submit --master yarn --executor-memory 5g --executor-cores 1 --num-executors 160 /sparkusecase/horovod/keras_spark_horovod_rossmann_estimator.py --epochs 10 --data-dir hdfs:///user/hdfs/tr-4570/experiments/horovod --local-submission-csv /tmp/submission_1.csv --local-checkpoint-file /tmp/checkpoint/ > /tmp/keras_spark_horovod_rossmann_estimator_yarn.log 2>&1
El tiempo de ejecución resultante se mejoró de la siguiente manera:
real8m13.728s user7m48.421s sys1m26.063s
Con el modelo y paralelismo de datos de Horovod en Spark, vimos una aceleración del tiempo de ejecución de 5.29x de yarn
vs local
modo con diez épocas de entrenamiento. Se muestra en la siguiente figura con las leyendas HDFS
y.. Local
. El entrenamiento del modelo TensorFlow DNN subyacente puede acelerarse más con GPU, si está disponible. Tenemos pensado llevar a cabo estas pruebas y publicar los resultados en un futuro informe técnico.
En nuestra siguiente prueba se compararon los tiempos de ejecución con los datos de entrada almacenados en NFS frente a HDFS. Se montó el volumen NFS en el AFF A800 /sparkdemo/horovod
En los cinco nodos (un maestro, cuatro trabajadores) de nuestro clúster de Spark. Hicimos un comando similar al de pruebas anteriores, con el --data- dir
Ahora el parámetro señala el montaje NFS:
(base) [root@n138 horovod]# time spark-submit --master yarn --executor-memory 5g --executor-cores 1 --num-executors 160 /sparkusecase/horovod/keras_spark_horovod_rossmann_estimator.py --epochs 10 --data-dir file:///sparkdemo/horovod --local-submission-csv /tmp/submission_2.csv --local-checkpoint-file /tmp/checkpoint/ > /tmp/keras_spark_horovod_rossmann_estimator_nfs.log 2>&1
El tiempo de ejecución resultante con NFS fue el siguiente:
real 5m46.229s user 5m35.693s sys 1m5.615s
Hubo otro 1,3x de aceleración, como se muestra en la siguiente figura. Por lo tanto, con un almacenamiento all-flash de NetApp conectado a su clúster, los clientes disfrutan de las ventajas de una transferencia y distribución de datos rápidas para flujos de trabajo de Horovod Spark, obteniendo una aceleración de 7,55 veces superior en comparación con ejecutarse en un único nodo.
Modelos de aprendizaje profundo para el rendimiento de la predicción CTR
Para sistemas de recomendación diseñados para maximizar CTR, debe aprender sofisticadas interacciones de funciones detrás de comportamientos de usuario que se pueden calcular matemáticamente desde orden bajo hasta orden alto. Tanto las interacciones de funciones de bajo orden como las de alto nivel deben ser igualmente importantes para un buen modelo de aprendizaje profundo sin orientarse hacia uno o hacia otro. DeepFM, una red neuronal basada en máquinas para la factorización profunda, combina máquinas de factorización para recomendaciones y aprendizaje profundo para el aprendizaje de funciones en una nueva arquitectura de redes neuronales.
Aunque las máquinas de factorización convencionales modelan las interacciones de funciones emparejadas como producto interno de vectores latentes entre las características y pueden teóricamente capturar información de alto orden, en la práctica, los profesionales de aprendizaje automático normalmente solo utilizan interacciones de funciones de segundo orden debido a la alta complejidad del almacenamiento y la computación. Variantes de redes neuronales profundas como las de Google "Modelos amplios profundos" por otro lado, aprende sofisticadas interacciones de características en una estructura de red híbrida combinando un modelo lineal amplio y un modelo profundo.
Hay dos entradas para este modelo ancho y profundo, uno para el modelo ancho subyacente y el otro para el profundo, la última parte de la cual todavía requiere ingeniería de características expertas y por lo tanto hace la técnica menos generalizable a otros dominios. A diferencia del modelo ancho y profundo, DeepFM puede ser entrenado eficientemente con características RAW sin ninguna ingeniería de características porque su gran parte y la parte profunda comparten la misma entrada y el vector de incrustación.
Primero procesamos el Criteo train.txt
(11 GB) en un archivo CSV denominado ctr_train.csv
Almacenados en un montaje NFS /sparkdemo/tr-4570-data
uso run_classification_criteo_spark.py
de la sección "“Guiones de Python para cada caso de uso principal”." Dentro de este script, la función process_input_file
realiza varios métodos de cadena para quitar fichas e insertar ‘,’
como delimitador y. ‘\n’
como nueva línea. Tenga en cuenta que sólo necesita procesar el original train.txt
una vez, para que el bloque de código se muestre como comentarios.
Para las siguientes pruebas de distintos modelos de aprendizaje profundo, utilizamos ctr_train.csv
como archivo de entrada. En las pruebas posteriores, el archivo CSV de entrada se leyó en un Spark DataFrame con un esquema que contiene un campo de ‘label’
, funciones densas de enteros ['I1', 'I2', 'I3', …, 'I13']
, y las características dispersas ['C1', 'C2', 'C3', …, 'C26']
. Lo siguiente spark-submit
El comando toma en una entrada CSV, entrena modelos DeepFM con 20% de división para validación cruzada y elige el mejor modelo después de diez épocas de entrenamiento para calcular la precisión de predicción en el conjunto de pruebas:
(base) [root@n138 ~]# time spark-submit --master yarn --executor-memory 5g --executor-cores 1 --num-executors 160 /sparkusecase/DeepCTR/examples/run_classification_criteo_spark.py --data-dir file:///sparkdemo/tr-4570-data > /tmp/run_classification_criteo_spark_local.log 2>&1
Tenga en cuenta que desde el archivo de datos ctr_train.csv
Es superior a 11 GB, debe establecer un valor suficiente spark.driver.maxResultSize
mayor que el tamaño del conjunto de datos para evitar errores.
spark = SparkSession.builder \ .master("yarn") \ .appName("deep_ctr_classification") \ .config("spark.jars.packages", "io.github.ravwojdyla:spark-schema-utils_2.12:0.1.0") \ .config("spark.executor.cores", "1") \ .config('spark.executor.memory', '5gb') \ .config('spark.executor.memoryOverhead', '1500') \ .config('spark.driver.memoryOverhead', '1500') \ .config("spark.sql.shuffle.partitions", "480") \ .config("spark.sql.execution.arrow.enabled", "true") \ .config("spark.driver.maxResultSize", "50gb") \ .getOrCreate()
En el anterior SparkSession.builder
la configuración también está activada "Flecha Apache", Que convierte un DataFrame de Spark en un DataFrame de Pandas con el df.toPandas()
método.
22/06/17 15:56:21 INFO scheduler.DAGScheduler: Job 2 finished: toPandas at /sparkusecase/DeepCTR/examples/run_classification_criteo_spark.py:96, took 627.126487 s Obtained Spark DF and transformed to Pandas DF using Arrow.
Tras la división aleatoria, hay más de 36 M de filas en el conjunto de datos de entrenamiento y 9M de muestras en el conjunto de pruebas:
Training dataset size = 36672493 Testing dataset size = 9168124
Dado que este informe técnico se centra en las pruebas de CPU sin utilizar ninguna GPU, es imprescindible crear TensorFlow con indicadores adecuados del compilador. Este paso evita llamar a bibliotecas aceleradas por GPU y aprovecha al máximo las instrucciones de TensorFlow Advanced Vector Extensions (AVX) y AVX2. Estas características están diseñadas para cálculos algebraicos lineales como adición vectorizada, multiplicaciones de matrices dentro de un avance de alimentación o entrenamiento DNN de reproducción posterior. La instrucción Multiply Add (FMA) fusionada disponible con AVX2 utilizando registros de coma flotante de 256 bits (FP) es ideal para código entero y tipos de datos, lo que da como resultado una aceleración de hasta dos veces. En lo que respecta a los tipos de datos y código FP, AVX2 logra una aceleración del 8 % con respecto a AVX.
2022-06-18 07:19:20.101478: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Para crear TensorFlow a partir de origen, NetApp recomienda usar "Bazel". Para nuestro entorno, hemos ejecutado los siguientes comandos en el intérprete de comandos del shell para instalar dnf
, dnf-plugins
, Y Bazel.
yum install dnf dnf install 'dnf-command(copr)' dnf copr enable vbatts/bazel dnf install bazel5
Debe habilitar GCC 5 o posterior para utilizar las funciones C++17 durante el proceso de compilación, que proporciona RHEL con la biblioteca de colecciones de software (SCL). Los siguientes comandos se instalan devtoolset
Y GCC 11.2.1 en nuestro clúster RHEL 7.9:
subscription-manager repos --enable rhel-server-rhscl-7-rpms yum install devtoolset-11-toolchain yum install devtoolset-11-gcc-c++ yum update scl enable devtoolset-11 bash . /opt/rh/devtoolset-11/enable
Tenga en cuenta que los dos últimos comandos se habilitan devtoolset-11
, que utiliza /opt/rh/devtoolset-11/root/usr/bin/gcc
(GCC 11.2.1). También, asegúrese de que su git
La versión es superior a 1.8.3 (se incluye con RHEL 7.9). Consulte este apartado "artículo" para la actualización git
a 2.24.1.
Asumimos que ya ha clonado el repo maestro TensorFlow más reciente. A continuación, cree un workspace
directorio con un WORKSPACE
Archivo para crear TensorFlow a partir de origen con AVX, AVX2 y FMA. Ejecute el configure
Y especifique la ubicación binaria Python correcta. "CUDA" Está deshabilitado para nuestras pruebas porque no utilizamos una GPU. A. .bazelrc
el archivo se genera de acuerdo con su configuración. Además, hemos editado el archivo y configurado build --define=no_hdfs_support=false
Para habilitar el soporte de HDFS. Consulte .bazelrc
en la sección "“Guiones de Python para cada caso de uso principal”," para ver una lista completa de valores y marcas.
./configure bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both -k //tensorflow/tools/pip_package:build_pip_package
Después de crear TensorFlow con los indicadores correctos, ejecute la siguiente secuencia de comandos para procesar el conjunto de datos de anuncios de visualización Criteo, formar un modelo DeepFM y calcular el área bajo la curva de características operativas del receptor (AUC ROC) a partir de las puntuaciones de predicción.
(base) [root@n138 examples]# ~/anaconda3/bin/spark-submit --master yarn --executor-memory 15g --executor-cores 1 --num-executors 160 /sparkusecase/DeepCTR/examples/run_classification_criteo_spark.py --data-dir file:///sparkdemo/tr-4570-data > . /run_classification_criteo_spark_nfs.log 2>&1
Después de diez épocas de entrenamiento, hemos obtenido la puntuación del AUC en el conjunto de datos de pruebas:
Epoch 1/10 125/125 - 7s - loss: 0.4976 - binary_crossentropy: 0.4974 - val_loss: 0.4629 - val_binary_crossentropy: 0.4624 Epoch 2/10 125/125 - 1s - loss: 0.3281 - binary_crossentropy: 0.3271 - val_loss: 0.5146 - val_binary_crossentropy: 0.5130 Epoch 3/10 125/125 - 1s - loss: 0.1948 - binary_crossentropy: 0.1928 - val_loss: 0.6166 - val_binary_crossentropy: 0.6144 Epoch 4/10 125/125 - 1s - loss: 0.1408 - binary_crossentropy: 0.1383 - val_loss: 0.7261 - val_binary_crossentropy: 0.7235 Epoch 5/10 125/125 - 1s - loss: 0.1129 - binary_crossentropy: 0.1102 - val_loss: 0.7961 - val_binary_crossentropy: 0.7934 Epoch 6/10 125/125 - 1s - loss: 0.0949 - binary_crossentropy: 0.0921 - val_loss: 0.9502 - val_binary_crossentropy: 0.9474 Epoch 7/10 125/125 - 1s - loss: 0.0778 - binary_crossentropy: 0.0750 - val_loss: 1.1329 - val_binary_crossentropy: 1.1301 Epoch 8/10 125/125 - 1s - loss: 0.0651 - binary_crossentropy: 0.0622 - val_loss: 1.3794 - val_binary_crossentropy: 1.3766 Epoch 9/10 125/125 - 1s - loss: 0.0555 - binary_crossentropy: 0.0527 - val_loss: 1.6115 - val_binary_crossentropy: 1.6087 Epoch 10/10 125/125 - 1s - loss: 0.0470 - binary_crossentropy: 0.0442 - val_loss: 1.6768 - val_binary_crossentropy: 1.6740 test AUC 0.6337
De un modo similar a los casos de uso anteriores, comparamos el tiempo de ejecución del flujo de trabajo de Spark con los datos alojados en diferentes ubicaciones. En la siguiente figura, se muestra una comparación de la predicción del CTR de aprendizaje profundo para un tiempo de ejecución de los flujos de trabajo de Spark.