softmax_cross_entropy_with_logits_v2 - tensorflow tutorial español pdf
¿Softmax jerárquico escalable y eficiente en tensorflow? (1)
Usted menciona que quiere un rendimiento de clase GPU:
pero ahora mantiene todo en la CPU y ralentiza un poco las cosas
y desea utilizar diccionarios de tamaño oculto de 300 unidades y 10 millones de palabras.
Esto significa que (asumiendo que es float32
), necesitará 4 * 300 * 10M * 2 bytes = 24 GB solo para almacenar los parámetros y el gradiente de la capa de salida.
Hierarchical Softmax (HSM) no reduce los requisitos de memoria, solo acelera el entrenamiento.
Siendo realistas, necesitarás mucha más memoria de GPU, porque también necesitarás almacenar:
Otros parámetros y sus gradientes.
datos del optimizador, por ejemplo , velocidades en el entrenamiento de impulso
Activaciones y datos temporales backpropagated.
gastos generales específicos del marco
Por lo tanto, si desea realizar todos los cálculos en las GPU , no tendrá más remedio que distribuir esta capa en varias GPU de alta memoria.
Sin embargo, ahora tienes otro problema:
Para concretar esto, supongamos que tiene un HSM de 2 niveles con clases 3K, con 3K palabras por clase (9M palabras en total). Distribuye las clases 3K en 8 GPU, de modo que cada una de ellas alberga 384 clases.
¿Qué sucede si todas las palabras de destino en un lote son de las mismas 384 clases, es decir , pertenecen a la misma GPU? Una GPU hará todo el trabajo, mientras que las otras 7 la esperarán.
El problema es que incluso si las palabras de destino en un lote pertenecen a diferentes GPU, seguirá teniendo el mismo rendimiento que en el peor de los casos, si desea realizar este cálculo en TensorFlow (Esto se debe a que TensorFlow es un " marco de especificación y ejecución "- el gráfico computacional es el mismo para el mejor y el peor de los casos)
¿Cuál es la mejor manera de hacer esto para que sea escalable a grandes cuentas de clase y eficiente?
La ineficiencia anterior del paralelismo del modelo (cada GPU debe procesar todo el lote) sugiere que se debe tratar de mantener todo en un solo lugar.
Supongamos que está implementando todo en el host o en 1 GPU gigantesca.
Si no está modelando secuencias, o si lo está, pero solo hay una salida para toda la secuencia, entonces la sobrecarga de memoria de la copia de los parámetros a los que hizo referencia es insignificante en comparación con los requisitos de memoria descritos anteriormente:
400 == tamaño de lote << número de clases == 3K
En este caso, simplemente podría utilizar
gather
oembedding_lookup
(aunque la copia es ineficiente)Sin embargo, si modela secuencias de longitud, por ejemplo, 100, con salida en cada paso de tiempo, entonces la copia de parámetros se convierte en un gran problema.
En este caso, creo que tendrá que desplegar a C ++ / CUDA C e implementar toda esta capa y su gradiente como una operación personalizada.
Estoy interesado en implementar un modelo jerárquico de softmax que pueda manejar grandes vocabularios, por ejemplo en el orden de las clases de 10M. ¿Cuál es la mejor manera de hacer esto para que sea escalable a grandes cuentas de clase y eficiente? Por ejemplo, al menos un documento ha demostrado que el HS puede alcanzar una aceleración de ~ 25x para voces vocales grandes cuando se usa un árbol de 2 niveles donde se clasifica cada nodo sqrt(N)
. También estoy interesado en una versión más general para un árbol de profundidad arbitrario con un factor de ramificación arbitrario.
Hay algunas opciones que veo aquí:
1) Ejecute tf.gather
para cada lote, donde recopilamos los índices y las divisiones. Esto crea problemas con lotes grandes y árboles gruesos donde ahora los coeficientes se están duplicando mucho, lo que lleva a errores de OOM.
2) Similar al # 1, podríamos usar tf.embedding_lookup
que mantendría la ayuda con los errores de OOM, pero ahora mantiene todo en la CPU y ralentiza un poco las cosas.
3) Use tf.map_fn
con parallel_iterations=1
para procesar cada muestra por separado y volver a usar recolectar. Esto es mucho más escalable, pero en realidad no se acerca a la aceleración de 25x debido a la serialización.
¿Hay una mejor manera de implementar HS? ¿Hay diferentes maneras de árboles profundos y estrechos en comparación con los cortos y los árboles anchos?