- LLM in a Flash permite ejecutar inferencia en dispositivos con memoria limitada al almacenar en memoria flash los parámetros de LLM que son más grandes que la DRAM y llevar a la DRAM solo las partes necesarias
- Basado en un modelo de costo de inferencia que refleja las características de acceso de la memoria flash, reduce la cantidad de datos transferidos y favorece lecturas de fragmentos más grandes y continuos
- windowing reutiliza neuronas activadas previamente, y row-column bundling aprovecha la fortaleza del acceso secuencial en flash para reducir cuellos de botella
- Al combinar ambas técnicas, es posible ejecutar modelos de hasta 2 veces el tamaño de la DRAM disponible, con una inferencia 4 a 5 veces más rápida en CPU y 20 a 25 veces más rápida en GPU frente a una carga simple
- La combinación de reconocimiento de dispersión, carga adaptativa al contexto y diseño orientado al hardware amplía la viabilidad de ejecutar LLM en dispositivos con memoria limitada
Inferencia de LLM basada en memoria flash
- Los modelos de lenguaje de gran tamaño logran alto rendimiento en diversas tareas de procesamiento de lenguaje natural, pero sus requisitos de cómputo y memoria son elevados, lo que dificulta ejecutarlos en dispositivos con capacidad de DRAM limitada
- LLM in a Flash aborda esta limitación almacenando los parámetros del modelo en memoria flash y trayendo a la DRAM bajo demanda solo los datos necesarios durante la inferencia
- En el centro del enfoque hay un modelo de costo de inferencia ajustado al funcionamiento de la memoria flash
- Está optimizado para reducir la cantidad de datos transferidos desde la flash
- Está diseñado para leer los datos en fragmentos más grandes y continuos
Dos técnicas para reducir la transferencia y el patrón de lectura
- windowing reutiliza neuronas activadas previamente para reducir la cantidad de datos que deben transferirse de la flash a la DRAM
- row-column bundling aumenta el tamaño de los fragmentos de datos leídos desde la flash, en línea con la fortaleza de la memoria flash para el acceso secuencial a datos
- Al usar ambas técnicas juntas, se pueden ejecutar modelos de hasta 2 veces el tamaño de la DRAM disponible
- La mejora en velocidad de inferencia frente a un método de carga simple varía según el hardware
- En CPU, es 4 a 5 veces más rápida
- En GPU, es 20 a 25 veces más rápida
- Este diseño integra reconocimiento de dispersión, carga adaptativa al contexto y diseño orientado al hardware para hacer posible la inferencia de LLM en entornos con memoria limitada
1 comentarios
Opiniones de Hacker News
Ese paper se apoya en la técnica de aprovechamiento de sparsity del paper Deja Vu, que ya es bastante complejo, así que me tomó tiempo entenderlo.
Deja Vu considera que incluso los modelos con baja sparsity en los pesos tienen una alta “sparsity contextual” (contextual sparsity). Es decir, aparecen muchos ceros en el vector resultante de la multiplicación de matrices, pero qué posiciones se vuelven cero depende de la entrada.
Si se aprovecha esa sparsity, se puede omitir la carga de algunas filas de la matriz; para obtener ganancias de rendimiento hay que predecir de antemano qué filas omitir, y esa predicción puede hacerse con una matriz de bajo rango.
El paper de Apple propone que este hallazgo ayuda no solo al rendimiento al cargar desde RAM, sino también a cargar desde memoria flash sin sacrificar demasiado ancho de banda.
Las matrices de atención son relativamente livianas, y el objetivo que debe cargarse de forma dispersa es la FFN. Además, si se predice la salida de la capa ReLU en vez de la entrada de la FFN, se obtiene una sparsity mucho mejor. Si se puede predecir que “después de la multiplicación de matrices, antes de ReLU, este slot del vector será negativo”, entonces se puede no cargar esa columna de la matriz y devolver 0.
La propuesta es que la mayoría de las filas de la FFN ni siquiera necesitan cargarse, y que para cada FFN se mantenga una caché de las filas usadas recientemente y se actualice desde flash cuando haga falta. También hay más detalles sobre la carga por chunks y la correlación entre capas de proyección, pero la idea central parece ser esta.
FFN significa Feed Forward Network y, en los transformers, son los bloques más grandes.
Me da curiosidad qué proporción del modelo puede dejar de cargarse antes de que empiece a notarse una diferencia real de rendimiento.
Por ejemplo, si se quiere mantener el 90% del rendimiento que se obtiene al cargarlo completo en RAM, quisiera saber si basta con usar la mitad de la memoria, o si se necesita el 90%, o el 95%.
Al final, cuando se reduce la RAM, la cuestión es qué tan rápido se pierde rendimiento frente al máximo posible. El gráfico compara este algoritmo con el algoritmo base en escenarios de poca RAM, que es algo distinto, pero es una buena pregunta.
Si se puede obtener buen rendimiento sin cargar en la memoria del teléfono un modelo completo de 8 GB, claramente sería útil.
Vale la pena leer el paper completo; es un trabajo bastante interesante: https://arxiv.org/pdf/2312.11514
Lo que destaca el paper son dos técnicas complementarias para minimizar la transferencia de datos y maximizar el throughput de la memoria flash.
Windowing reutiliza los valores de activación de los tokens calculados recientemente y carga solo los parámetros necesarios para los últimos tokens, reduciendo así la cantidad de solicitudes de I/O para cargar pesos.
Row-column bundling guarda concatenadas las filas y columnas de las capas up-projection y down-projection, de modo que se lean chunks continuos más grandes desde flash, y al leer chunks grandes aumenta el throughput.
En teoría, cuando una parte del modelo está en flash, el tiempo de inferencia de un solo token debería ser igual al tiempo de inferencia con todo el modelo en RAM más el tiempo de cargar la parte del modelo que está en flash.
Supongo que no hace falta volver a escribir en flash, aunque no soy experto en LLM y podría estar equivocado.
Si hay muchas más de 10 capas, parecería posible dejar solo una pequeña parte en RAM e ir cargando una capa a la vez. La mayoría de los LLM tienen decenas de capas, así que suena plausible.
Si durante la inferencia la RAM no es el cuello de botella, quizá también se podría hacer una transferencia DMA de la siguiente capa desde flash a RAM mientras se infiere la capa actual. En un sistema de un solo procesador, probablemente no funcionaría bien por el cuello de botella de la RAM.
En un sistema de doble procesador, quizá un procesador podría cargar la siguiente capa en RAM mientras el otro infiere la capa anterior, y así se podrían ejecutar LLM muy grandes con poca RAM.
Ahora mismo estoy sentado junto a un montón de piezas para armar una nueva máquina de IA para LLM. Es una z840 de doble procesador, así que tengo muchas ganas de probar estas cosas por mi cuenta.
Algo que llama la atención es que los dispositivos de Apple tienen muy poca RAM en comparación con dispositivos similares de la competencia.
En parte se debe a que los equipos de software de Apple usan lenguajes más eficientes como Objective-C, y en parte a que las apps de iOS no tienen que apuntar a una enorme variedad de resoluciones de pantalla. Por eso hay relativamente menos necesidad de cargar texturas de alta resolución y luego reducirlas.
Además, incluso comprando a la escala de Apple, la RAM no se abarata mucho, así que aumentar la RAM golpea más los márgenes que agregar otras funciones.
Pero como los LLM son, por naturaleza, grandes consumidores de RAM, todas esas decisiones se vuelven en su contra. Sin importar qué técnicas de ahorro de memoria se usen, los competidores con más RAM podrán meter modelos más grandes, mejores y más inteligentes.
Quiero comprar una Mac pronto y de verdad me cuesta decidir cuánta RAM pedir. Es más difícil porque tengo un presupuesto limitado. Si no tuviera límites, creo que iría por al menos 32 GB.
Todavía espero que Apple cambie su política de precios de RAM, pero probablemente sea una expectativa vana.
También se puede ver la implementación relacionada: https://opensource.apple.com/source/xnu/xnu-2050.18.24/libke...
Además, los dispositivos de Apple admiten una función llamada “jetsam”, que libera memoria cerrando apps que no se usan o que están en segundo plano para que las apps de alta prioridad sigan funcionando sin problemas: https://developer.apple.com/documentation/xcode/identifying-...
Estoy abierto a recomendaciones de laptops Linux silenciosas o casi sin ruido. La mayoría hace girar mucho el ventilador, y estaría dispuesto a sacrificar parte del rendimiento de CPU a cambio de silencio. También estaría bien poder activar y desactivar fácilmente un modo silencioso.
Hasta ahora no he visto nada que iguale la quietud de la MacBook Air, y me encantaría escuchar sobre algún producto que demuestre que estoy equivocado.
Por supuesto, también sería bueno que fuera más barata o que permitiera reemplazar la RAM. Uso la MacBook Air principalmente para servicios web y como terminal remota para conectarme a servidores Linux que uso para compilar proyectos grandes y para hosting en casa/autohospedado.
Es evidente que el calendario se adelantó, pero no creo que su hipótesis sea incorrecta.
Entiendo este tema solo de forma limitada, pero me pregunto si con este enfoque se podrían ejecutar LLM sin conexión en teléfonos.
Si fuera posible, se abrirían muchas aplicaciones interesantes, como moderation de contenido asistida por IA sin enviar datos confidenciales a un servidor.
Por ejemplo, ayer apareció aquí una discusión de GitHub sobre ejecutar LLM en chips Apple A-series (iPhone): https://news.ycombinator.com/item?id=38703161
Me gusta que los artículos recientes lo llamen LLM y no “IA”. Así se entiende que trata sobre una tecnología específica y no sobre exageración de marketing.
Me pregunto en qué se diferencia esto de FlashAttention. Es confuso que usen términos parecidos y no expliquen la diferencia en el resumen.
Edición: parece que extendieron dos mecanismos distintos dentro del framework de flash. El título del paper podría haber sido mejor, pero lo explican en las primeras páginas.
En la conclusión esperaba una sección sobre “cómo se expondrá esta función a los usuarios”, aunque quizá eso quede fuera del alcance del paper.
Me pregunto si esta función llegará como una llamada de API o una configuración en CoreML, por ejemplo especificando un flag use_flash, o si será una optimización de runtime invisible para el usuario.
También me pregunto si alguien conoce alguna buena presentación o charla donde Apple explique el roadmap de desarrollo de CoreML, Metal, etc.
¿Apple adquirió una empresa iraní?
[0]: https://www.geekwire.com/2020/exclusive-apple-acquires-xnor-...
Sé que los enfoques son distintos, pero como ambos aprovechan la memoria flash, esperaba que este paper al menos mencionara FlashAttention [1]
[1] https://arxiv.org/abs/2205.14135
Según entiendo, FlashAttention se trata de patrones de acceso que aprovechan mejor la memoria local, en particular SRAM. Por ejemplo, mantener los datos en la caché L1 de la CPU o en un nivel equivalente de la GPU.
En otras palabras, FlashAttention trata sobre la parte más rápida que la DRAM, mientras que este paper aborda cómo descargar mejor hacia la parte más lenta que la DRAM.
En “el modelo OPT 6.7B muestra, por ejemplo, una dispersión del 97% notable dentro de las capas FFN”, ¿alguien sabe qué significa exactamente esa métrica?
Me pregunto si quiere decir que el 97% de los valores de la capa son cero, o que se puede comprimir hasta el 3% del tamaño.
Pero como ese 3% que se activa no es fijo, no se puede eliminar por completo el 97% restante. El paper parece decir que pueden predecir con bastante precisión el 3% activo y así hacerlo más rápido sin perder demasiada exactitud.