Análisis profundo de la inferencia de LLM a escala — Harshul Jain, Audible & Tanmay Sah, Independent AI Researcher
AAI Engineer
컴퓨터/소프트웨어경제 뉴스AI/미래기술
스크립트
00:00:00Buenas tardes a todos. Mi nombre es Harshal Jain y él es Tanmisha. Y nos
00:00:21gustaría daros la bienvenida a este taller de dos horas sobre la inferencia de LLM.
00:00:26El objetivo de este taller es entender este dominio desde los primeros
00:00:33principios, profundizar en él y comprender qué está pasando en toda
00:00:39la industria. Un poco de antecedentes sobre nosotros. Soy ingeniero de software sénior en
00:00:47Audible. Llevo construyendo plataformas de datos de ML y AI los últimos cinco años y, por
00:00:53otra parte, he estado escribiendo este manual de código abierto sobre inferencia de LLM. Y
00:00:59Tanmay es modelador cuantitativo sénior en Xi'an's Bank Corporation. Ha
00:01:06terminado hace poco su doctorado y ha estado investigando activamente en los ámbitos de los
00:01:12verificadores de agentes y los modelos de mundo. Hagamos una rápida muestra de manos. ¿Quién es totalmente nuevo en la inferencia de LLM?
00:01:24De acuerdo, genial. ¿Y quién ha desplegado estos modelos en producción? Los han estado
00:01:33ajustando y sirviendo tráfico de producción. Muy bien, perfecto. Este
00:01:42taller está dirigido a niveles principiantes e intermedios. Todas las
00:01:48diapositivas y ejercicios están en el repositorio que compartiré en breve. Aquí tenéis la
00:01:56agenda rápida del taller. Empezaremos con el planteamiento del problema e intentaremos
00:02:01entender algunos de los puntos débiles de la inferencia de LLM. Luego veremos qué causa esos
00:02:08problemas y estableceremos nuestras bases a partir de ahí. Después nos adentraremos en dos
00:02:14tipos de optimizaciones que realizamos: las optimizaciones de modelos y las
00:02:19optimizaciones de servicio. A continuación, empezaremos a conocer los diferentes motores de servicio
00:02:25disponibles para desplegar nuestras soluciones de inferencia de LLM en producción. Mostraremos algunas
00:02:32comparativas de rendimiento y una tabla de decisión sobre qué motor utilizar.
00:02:39Genial. Para entender los puntos débiles, primero necesitamos saber qué es la inferencia de LLM. Así que
00:02:47probablemente muchos de nosotros ya lo sepamos, pero cualquier cosa que le pidas hacer a tu inteligencia artificial,
00:02:55ya sea generar un vídeo, audio, analizar texto, revisar tus informes médicos o
00:03:02facturas de impuestos, todo eso es inferencia de LLM. Este mercado ronda hoy los 23.000 millones de dólares.
00:03:12SemiAnalysis compartió recientemente que si quieres modelar consultas de búsqueda de Google con LLMs, necesitas un gasto desorbitado de unos 36.000 millones de dólares.
00:03:25Y el coste por consulta tiene que ser inferior a medio centavo para que tu negocio de búsquedas siga siendo rentable.
00:03:33Por otro lado, Business Insider mencionó que la IA debe aplicarse correctamente y todo el mundo tiene que empezar a auditar y presupuestar su uso de tokens.
00:03:43Y todo esto ocurre porque el hardware es limitado, el cálculo es caro y la inferencia es cara.
00:03:50Y con la creciente necesidad de un uso mayor de la IA, este coste de inferencia no para de subir.
00:04:03Esta estadística es antigua de OpenAI, pero sigue siendo cierta.
00:04:11Si nos fijamos en los costes de entrenamiento de GPT-3, rondaban los 4,6 millones de dólares, siendo un coste único.
00:04:19Pero si ves los costes de inferencia, son recurrentes porque se trata de un coste operativo que escala con cada usuario que entra, con cada token que llega y con cada sesión que se inicia en la IA.
00:04:36Básicamente hay dos formas de contrarrestar esto: una es reducir el uso de tokens.
00:04:47La alternativa es intentar optimizar tus soluciones de inferencia como proveedor de servicios de inferencia para tus clientes y para ti mismo.
00:04:58Por eso hemos estado viendo muchísimas soluciones nuevas apareciendo constantemente.
00:05:06La idea es construir esas bases que nos ayuden a entender y evaluar lo que sea que salga próximamente.
00:05:18Para empezar, haremos una pequeña demostración sobre los diferentes problemas que surgen en la inferencia.
00:05:28Este es un repositorio.
00:05:31Podéis clonarlo o también abrirlo en GitHub.
00:05:36Se llama LLM inference at scale.
00:05:39Como contexto, hace cuatro meses, cuando no sabía nada sobre inferencia de LLM, empecé a aprender.
00:05:46Vi que muchos recursos estaban muy dispersos.
00:05:49Así que empezamos a recopilarlos todos en un solo lugar para que pudiera beneficiar a la gente.
00:05:55Voy a salir de este modo de presentación y pasar al modo extendido.
00:06:11En este repositorio, si miráis el archivo README, veréis un enlace a las diapositivas.
00:06:27Estará en esta carpeta donde tenéis un archivo PPTX y un informe de pruebas de rendimiento.
00:06:34Podéis descargarlo siempre y, para los ejemplos prácticos, tenemos un par de cuadernos de Jupyter.
00:06:43Hemos colaborado con Molab, una alternativa a Google Colab, que os proporciona una GPU RTX 6000 gratuita.
00:06:54Es una GPU con 100 GB de RAM y ya hemos preparado estos cuadernos para que sea fácil experimentar y todos los recursos estén configurados previamente.
00:07:09Empezaremos con una demo sencilla A.
00:07:16Dejadme comprobar una cosa.
00:07:31Cuando se trata de inferencia, necesitas realizarla sobre un modelo determinado, ¿verdad?
00:07:40Para este taller, estamos usando un modelo sencillo Mistral 7B.
00:07:45Es un modelo pequeño de unos 15 GB de tamaño.
00:07:49Vamos a cargarlo en la GPU.
00:07:53También veremos algunas estadísticas de la GPU.
00:07:58Vemos que estamos trabajando con la 6000 Blackwell.
00:08:01Quizás penséis que no ejecuto las celdas porque no me fío del wifi de las conferencias.
00:08:08Así que repasaré los resultados que obtuvimos en las ejecuciones previas.
00:08:18Tenemos una GPU de 102 GB.
00:08:22Lo primero que se me ocurre es cómo es el consumo de memoria al hacer la inferencia de LLM.
00:08:31Cargo este modelo y veo que ocupa unos 15 GB.
00:08:37Así que me quedan aproximadamente 87,5 GB libres.
00:08:40Ahora, al realizar la inferencia, noto que cuantos más inputs paso, mayor es la memoria requerida.
00:08:52Aumenta despacio, pero sigue incrementándose.
00:08:56Imagina que tienes una longitud de contexto de unos 4000, 16000 o 32000 tokens.
00:09:03Esta memoria puede crecer muchísimo y podrías encontrarte con problemas de falta de memoria (OOM).
00:09:12Sin duda, este es tu primer problema: la memoria aumenta a medida que lo hacen los tokens.
00:09:18En forma de visualización sencilla, se ve así.
00:09:24El segundo problema que notarás es que el tiempo hasta el primer token es muy, muy lento.
00:09:32Lo medimos con una métrica llamada TTFT.
00:09:35Es su forma abreviada.
00:09:37Y cuando intentas medir el TTFT según el tamaño de entrada, ves que cuanto mayor es el contexto, más lento resulta el TTFT.
00:09:52Así que ya tenemos dos problemas.
00:09:54Tu memoria aumenta con el tamaño de los tokens.
00:09:56Tu TTFT aumenta con el tamaño de los tokens.
00:09:59Perdón, no el tamaño de los tokens, sino el tamaño del contexto.
00:10:07Y el tercero es el rendimiento (throughput).
00:10:09El rendimiento consiste en cuántos tokens puedes servir por segundo.
00:10:13Y a cuántos usuarios puedes dar servicio por segundo.
00:10:16Si usas una implementación muy, muy básica en tu sistema local, será de carácter secuencial.
00:10:24De modo que si envías cinco solicitudes, las cinco se atenderán de forma secuencial en lugar de en paralelo.
00:10:31Por lo tanto, tu solicitud tardará más en completarse si tienes múltiples usuarios.
00:10:40Estos son los tres problemas.
00:10:43Hay un cuarto.
00:10:44No lo he descrito aquí.
00:10:45Seguramente desarrollaremos esa intuición a medida que avancemos.
00:10:48Pero recordemos que estos son los tres problemas: la memoria, el TTFT y el rendimiento.
00:10:55Bien.
00:10:56Volveré a las diapositivas.
00:11:02De acuerdo.
00:11:03Perfecto.
00:11:04Debería ser esto.
00:11:17¿Se ve?
00:11:18Sí.
00:11:19Se ve.
00:11:20Se ve.
00:11:21Sí.
00:11:22Se ve.
00:11:23Se ve.
00:11:24Se ve.
00:11:25Sí.
00:11:26Se ve.
00:11:27Se ve.
00:11:28Sí.
00:11:29Se ve.
00:11:30Sí.
00:11:31Se ve.
00:11:32Sí.
00:11:33Se ve.
00:11:34Sí.
00:11:35Se ve.
00:11:36Se ve.
00:11:37Sí.
00:11:38Se ve.
00:11:39Sí.
00:11:40Se ve.
00:11:41Sí.
00:11:42Se ve.
00:11:43Sí.
00:11:44Se ve.
00:11:45Sí.
00:11:46Sí.
00:11:47En ese repositorio, si miráis la carpeta del taller, veréis el README y que el README
00:11:55contiene todos los enlaces, las diapositivas y las demos.
00:12:01¿Funciona eso?
00:12:06De acuerdo.
00:12:07Perfecto.
00:12:09De acuerdo.
00:12:10Perfecto.
00:12:16Bien.
00:12:17Comencemos a trabajar en las bases.
00:12:19Empecemos a comprender cuáles son las razones detrás de esos puntos débiles.
00:12:25Y para ello, tenemos que observar este pipeline de inferencia.
00:12:32Así que obtenemos un texto de entrada.
00:12:35Ese texto puede tener cualquier cantidad de palabras.
00:12:38Conviertes esas palabras en tokens.
00:12:41Por simplicidad, puedes asumir que una palabra equivale a un token.
00:12:46Luego los conviertes en incrustaciones y los envías a los transformers.
00:12:53Como hay 32 capas de transformers, pero eso es específico de Mistral 7.
00:12:58Los diferentes modelos tienen un número diferente de capas.
00:13:01Y luego generas un nuevo token.
00:13:04Y ese token básicamente regresa a la entrada.
00:13:06Luego generas otro token y eso continúa.
00:13:09Ahora, en todo este proceso, verás que el 95% de tu cómputo es tomado por estas capas de transformers.
00:13:18Así que vale la pena analizar qué es lo que ocurre dentro de esta capa de transformer.
00:13:24Dentro de esta capa de transformer, tendrás más capas.
00:13:28Tienes una capa de normalización.
00:13:30Tienes una capa de atención.
00:13:32Tienes una capa feed-forward y todo lo demás.
00:13:35Y la capa de atención es la que creo que se ha vuelto muy, muy famosa.
00:13:40La gente de Attention Is All You Need.
00:13:42Creo que eso es muy conocido.
00:13:44Así que la atención es la capa que consume más recursos de cómputo.
00:13:48Y necesitamos entender qué pasa dentro de esa capa de atención.
00:13:53¿Qué hace la atención?
00:13:56Si tienes un texto de entrada, necesita encontrar las puntuaciones de atención de cada token con respecto a todos los tokens anteriores.
00:14:05Y para hacer eso, lo que necesita hacer es proyectar cada token en un espacio de clave, consulta y valor.
00:14:14Así que, en términos más simples, entiende esto.
00:14:20Si tienes 10 tokens, entonces necesitas 10 vectores diferentes de consulta, clave y valor.
00:14:26Si hay 100 tokens, necesitarás 100 vectores de clave y valor.
00:14:31Si hay 1000 tokens, necesitarás 1000 vectores de clave y valor.
00:14:35Y por lo tanto, tu número de vectores de clave y valor aumenta a medida que aumentas el tamaño de la entrada.
00:14:45Y si calculas el tamaño de KV por token para un Mistral 7B, resulta ser de 131 KV.
00:14:54Esto se debe a que tienes dos vectores, K y V.
00:14:59Tienes que multiplicar el tamaño.
00:15:02Un vector tiene 128 dimensiones.
00:15:04Tienes que multiplicarlo por 32 capas de transformers.
00:15:08Y luego tienes que multiplicarlo por las cabezas KV.
00:15:11Para Mistral 7B, son las cabezas KV.
00:15:15No son 32 porque utiliza un tipo diferente de mecanismo de atención, del cual hablaremos sin duda.
00:15:23Pero sí, el tamaño de KV por token es de 131 KV.
00:15:30Ahora imagina que tienes un contexto de 4K, entonces ese tamaño se vuelve medio GB.
00:15:37Si haces un contexto de 16K, ese tamaño se convierte en 2.1 GB.
00:15:42Ahora multiplícalo por los usuarios.
00:15:45Supón que puedes atender a múltiples usuarios a la vez.
00:15:49Al mismo tiempo dentro de esa GPU, podrías tener 42 GB con un contexto de 4K y 80 usuarios.
00:15:58Y si tu GPU es de solo, digamos, 24 GB, ya te estás quedando sin memoria.
00:16:04Así que no puedes atender a tantos usuarios con tantos contextos.
00:16:11Para visualizar esto, observa la memoria de una GPU.
00:16:14La memoria de la GPU tiene los pesos del modelo, que son bastante fijos.
00:16:19Estos son pesos preentrenados.
00:16:21Hay un uso general que también es fijo.
00:16:24Eso también cambia, pero no cambia tanto.
00:16:29En general, puedes asumir que es fijo.
00:16:32Y luego hay una memoria restante.
00:16:35Esta memoria restante es la que utiliza tu memoria KV, como los vectores de clave y valor.
00:16:41Entonces, supón que tienes un usuario.
00:16:46Solo puedes atender tantos vectores de clave y valor o tantos tokens que quepan en toda esta memoria de 80 GB que queda.
00:17:00Así que podemos mostrar esto con una sencilla demostración también.
00:17:07De acuerdo, genial.
00:17:08De acuerdo, genial.
00:17:08Déjame ver si realmente puedo ejecutar esto.
00:17:14De acuerdo, genial.
00:17:15Déjame ver si realmente puedo ejecutar esto.
00:17:15¿Dónde diablos está esto?
00:17:15De acuerdo, genial.
00:17:16Déjame ver si realmente puedo ejecutar esto.
00:17:21¿Dónde diablos está esto?
00:17:22De acuerdo, genial.
00:17:23De acuerdo, genial.
00:17:24Sí.
00:17:25Sí.
00:17:25Entonces, verás, déjame ver si realmente puedo ejecutar esto.
00:17:31Déjame ver si realmente puedo ejecutar esto.
00:17:33Déjame ver si puedo ejecutar esto.
00:17:34Déjame ver si puedo ejecutar esto.
00:17:35Déjame ver si puedo ejecutar esto.
00:17:36Déjame ver si puedo ejecutar esto.
00:17:37De acuerdo, genial.
00:17:38Sí.
00:17:39Entonces, verás que la GPU está conectada.
00:17:43De acuerdo, genial.
00:17:44Sí.
00:17:45Entonces, verás que la GPU está conectada.
00:17:56Por lo tanto, aquí solo estamos intentando confirmar la memoria basándonos en las matemáticas y en la intuición que hemos construido.
00:18:13que hemos construido.
00:18:14Así que la memoria del modelo es, digamos, si tienes 7 mil millones de parámetros, estás usando
00:18:19una precisión de 16 bits.
00:18:20Tu memoria total resulta ser de 14.6 GB.
00:18:23Básicamente puedes verificar eso con las matemáticas.
00:18:27Así que, si haces todas esas matemáticas, el resultado es 14.6 GB.
00:18:33Ahora viene el KV y el tamaño de KV.
00:18:37Este tamaño de KV es como tus 131 KV por token.
00:18:42Y si haces esas matemáticas e intentas visualizar esto.
00:18:47Oh, claro.
00:18:52Espera.
00:18:53De acuerdo.
00:18:54Y luego simplemente visualicemos esto.
00:19:07De acuerdo, genial.
00:19:10Genial.
00:19:11Sí.
00:19:12Este es el gráfico de memoria.
00:19:15Si ves, a medida que tu contexto aumenta, tu memoria sigue aumentando.
00:19:21Otra cosa de la que hay que darse cuenta es que a medida que aumentan tus usuarios, tu memoria también aumenta.
00:19:28Por lo tanto, si quieres atender a 160 usuarios en una GPU, solo puedes admitir, solo puedes admitir
00:19:37una longitud de contexto menor.
00:19:40Siempre hay un equilibrio entre qué longitud de contexto puedes ofrecer frente a cuánto costo
00:19:47puedes ahorrar al colocar a múltiples usuarios o usuarios concurrentes en una sola GPU.
00:19:54Así que siempre tienes que aceptar ese compromiso.
00:19:57Y revisaremos eso en un par de diapositivas más.
00:20:06¿Puedes repetir, por favor?
00:20:10Lo siento.
00:20:11No te puedo escuchar.
00:20:12¿Ves un grupo diferente con diferente longitud de contexto para poder servir la memoria
00:20:25de la derecha?
00:20:26Sí.
00:20:27Genial.
00:20:28Genial.
00:20:29De acuerdo.
00:20:30Bien.
00:20:31Entonces, déjame retroceder.
00:20:32Eso era la memoria.
00:20:33Necesitamos entender por qué teníamos un tiempo hasta el primer token más lento cuando aumentábamos la longitud del contexto.
00:20:53de contexto.
00:20:54Para eso, necesitamos entender las dos fases de la inferencia.
00:20:58Y esas fases son la fase de prellenado y la fase de decodificación.
00:21:01Creo que todos habrán visto muchos artículos, pero solo queríamos explicarlo.
00:21:06Por lo tanto, cuando envías muchos tokens de entrada, lo que quieres hacer es construir esos vectores de clave y valor que mencioné para todos los tokens.
00:21:20Luego quieres calcular las puntuaciones de atención de cada token con respecto al token anterior.
00:21:27Toda esta operación que realizas consume muchísimas matrices.
00:21:31Es una operación con una carga de cómputo muy, muy pesada.
00:21:34Y todos sabemos que las GPUs son muy, muy adecuadas para cargas de trabajo con un cómputo pesado.
00:21:41Por eso llamamos al prellenado un proceso limitado por cómputo.
00:21:46Y toma algo de tiempo completarse.
00:21:49Por lo tanto, el tiempo que tarde esta fase en completarse es tu tiempo hasta el primer token.
00:21:55Así que, si tienes más tokens de entrada, tienes que generar más vectores de clave y valor.
00:22:02Tienes que hacer muchas más matemáticas de atención.
00:22:05Y debido a eso, tu TTFT se vuelve cada vez más lento.
00:22:12En cambio, una vez que generas un token, debes seguir haciendo esto para generar otros tokens, de forma secuencial, uno tras otro.
00:22:20Pero en ese proceso, cada vez tienes que construir los vectores clave y de valor de todos los tokens anteriores, lo cual es igual al pre-fill.
00:22:30Así como estabas construyendo vectores clave-valor allí, también los construyes aquí.
00:22:34Pero en la fase de decodificación, solo estás calculando las matemáticas de atención para el nuevo token.
00:22:40Y por eso es mucho menos, está menos orientado al cálculo.
00:22:45Y también se le llama limitado por memoria.
00:22:48Veremos en breve por qué se le llama limitado por memoria.
00:22:54Por lo tanto, en una línea de tiempo clásica, verías la fase de pre-fill y de decodificación así.
00:22:59Entonces, el tiempo que toma el pre-fill es tu tiempo hasta el primer token.
00:23:03Y luego el tiempo que toma cada paso de decodificación es básicamente tu latencia entre tokens.
00:23:12Así que esa es la cuarta métrica de la que debes preocuparte.
00:23:18Como, ¿cuál es el tiempo que toma tu paso de decodificación?
00:23:21De acuerdo.
00:23:22De acuerdo.
00:23:23Genial.
00:23:24Ahora, ¿por qué el paso de decodificación o por qué la decodificación toma tiempo?
00:23:34¿Y por qué se le llama una operación limitada por memoria?
00:23:38Intentemos entender eso.
00:23:40Para entenderlo, debemos observar cómo funciona básicamente el mapa de matrices en la GPU a un alto nivel.
00:23:47Por lo tanto, la GPU tiene dos tipos de memorias.
00:23:50Tienes una memoria de gran ancho de banda.
00:23:52Tienes una memoria compartida.
00:23:55La memoria de gran ancho de banda tiene un tamaño mayor, pero un ancho de banda menor.
00:24:01Por menor ancho de banda, quiero decir que puedes transferir datos fuera de ella a un ritmo menor.
00:24:06En comparación con la memoria compartida, esta es más pequeña en tamaño, pero tiene un ancho de banda muy, muy alto.
00:24:13Eso significa que puedes transferir datos hacia y desde ella de manera muy rápida.
00:24:19Entonces, cuando tienes que hacer un cálculo matricial, debes tomar los datos en fragmentos de la memoria de gran ancho de banda.
00:24:27Debes ponerlos en la memoria compartida.
00:24:30Hacer los cálculos.
00:24:32Y volver a escribir el resultado en la memoria de gran ancho de banda.
00:24:38Para la fase de pre-fill, cuando tienes que hacer esto, solo debes realizar este cálculo matricial una vez.
00:24:46Pero para la fase de decodificación, tienes que hacer este cálculo matricial una y otra vez porque estás generando cada uno de los tokens de forma secuencial.
00:24:59Y por lo tanto, no importa qué tan rápida sea tu decodificación, ya que ahora puedes transferir tus datos fuera de la memoria de gran ancho de banda hacia la memoria compartida a cierta velocidad.
00:25:14Porque estás limitado por la velocidad de ancho de banda de la memoria de gran ancho de banda.
00:25:18Y eso determina tu límite de tokens, es decir, a qué ritmo puedes realmente generar tokens a partir del paso de decodificación.
00:25:32Si miras esto en el gráfico de rendimiento (roofline plot), hay una sección izquierda que se denomina limitada por memoria.
00:25:42Matemáticamente, está regida por la intensidad aritmética.
00:25:47La intensidad aritmética es el número de operaciones de punto flotante que realizas por cada byte de datos transferido.
00:25:55Entonces, para el paso de decodificación, dado que estás transfiriendo muchos datos, como los vectores clave y de valor de todos los tokens anteriores, y los pesos del modelo,
00:26:08pero estás haciendo menos cálculos porque calculas las matemáticas de atención para un solo token,
00:26:13su intensidad aritmética es muy baja.
00:26:18Pero para la fase de pre-fill, transfieres los datos una vez, pero luego realizas este cálculo pesado.
00:26:27Y por lo tanto, su intensidad aritmética es muy alta.
00:26:30Así que ahora sabes, en términos matemáticos, por qué la intensidad aritmética del pre-fill es muy alta en comparación con la decodificación.
00:26:44De acuerdo.
00:26:46Esta es otra pequeña demostración.
00:26:51De acuerdo.
00:26:52Cada vez que tengo que hacerlo.
00:26:53De acuerdo.
00:26:54De acuerdo.
00:26:55Genial.
00:26:56Espero que esto ya esté listo.
00:26:58Así que sí.
00:26:59De nuevo, estamos cargando el modelo.
00:27:04Ahora, esto es como el coste del pre-fill.
00:27:09Lo que estamos haciendo básicamente es tomar el texto de entrada y luego intentar generar el paso de pre-fill y la cantidad de tiempo que toma.
00:27:22Vemos que a medida que aumentamos el tamaño de los tokens de entrada, este pre-fill aumenta.
00:27:28Sabes, y esta es la razón por la cual tu TTFT aumenta.
00:27:33Y luego está tu tiempo de decodificación.
00:27:36El tiempo de decodificación, en promedio, se mantiene más o menos igual.
00:27:41Y por lo tanto, si ignoras el arranque en frío, tu tiempo de decodificación está aproximadamente en la línea promedio.
00:27:50Todavía se ve afectado por el tamaño de la entrada.
00:27:57No es como si fuera un tiempo constante.
00:28:00Y es porque todavía necesita extraer los vectores clave y de valor de la memoria para todos los tokens anteriores.
00:28:07Así que todavía hay un pequeño incremento en el tiempo que se puede ver con el paso de decodificación.
00:28:15Y luego este es el gráfico de rendimiento clásico.
00:28:20De acuerdo.
00:28:22De acuerdo.
00:28:23Presentación.
00:28:24De acuerdo.
00:28:25De acuerdo.
00:28:26De acuerdo.
00:28:27Ahora intentemos entender la dimensión del rendimiento (throughput).
00:28:43Quieres entender a cuántos usuarios puedes atender realmente.
00:28:48Y creo que vimos un diagrama de la memoria de la GPU donde vimos que hay memoria libre para que crezcan los vectores clave y de valor.
00:28:56De acuerdo.
00:28:57Supongamos que tienes un solo usuario.
00:29:01¿Cuál es el tamaño total de KV que tienes y puedes soportar?
00:29:09Está definido por tu límite de contexto.
00:29:11El máximo de usuarios que puedes soportar es la disponibilidad de la memoria en la GPU dividida por el tamaño de clave y valor por usuario.
00:29:25Y cuando haces eso, resulta ser el número de usuarios concurrentes.
00:29:32Ahora, supón que tu GPU es fija, tu modelo es fijo, por lo que tu tamaño de KV por token es fijo.
00:29:46Solo quedan dos dimensiones aquí: el contexto y tus usuarios concurrentes.
00:29:53Si quieres atender a más usuarios concurrentes, debes reducir la longitud del contexto.
00:29:57Si reduces la longitud del contexto, podrías afectar tu calidad.
00:30:02Así que estas son las dos dimensiones entre las que estamos haciendo un equilibrio en este momento.
00:30:09Luego, si... ¿puedes realmente atender al número máximo de usuarios concurrentes?
00:30:17En un mundo ideal, probablemente no, porque cada negocio tiene un acuerdo de nivel de servicio (SLO) de latencia que debemos cumplir.
00:30:27Así que, si recuerdas, en el paso de decodificación dije que el tiempo de decodificación aumenta si tienes más entradas.
00:30:37También aumenta si tienes más usuarios.
00:30:40En última instancia, tu latencia entre tokens también se ve afectada si tienes un tamaño de lote mayor.
00:30:51Y tu TTFT también se ve afectado.
00:30:53Por lo tanto, ahora hay una tercera dimensión de la que debes preocuparte, que es tu latencia.
00:30:58Así que las tres dimensiones que tienes son la calidad, la latencia y el rendimiento (throughput).
00:31:04Esto se convierte en un triángulo de compensaciones donde tienes que elegir entre ellas.
00:31:11Para una aplicación de chat prémium, querrás priorizar definitivamente la calidad y la latencia.
00:31:21No querrías que tus usuarios esperen una latencia muy alta, o al menos no infinitamente.
00:31:30Siempre puedes sacrificar el número de usuarios que puedes soportar en la GPU y asumir ese coste, estando más obsesionado con el cliente.
00:31:39En el caso de una carga de trabajo de agentes asíncronos, querrás priorizar sin duda la calidad y el rendimiento.
00:31:53Porque estas son tareas de larga ejecución.
00:31:56Y querrás atender tantas tareas concurrentes como sea posible, pero con una calidad muy, muy alta.
00:32:06Y a menudo pensamos: “Bien, si la GPU es muy cara, tal vez no sea una buena opción para nosotros”.
00:32:19Pero resulta que esa podría ser la que te ofrezca el menor coste por millón de tokens.
00:32:27Pero realmente tienes que confiar en tus cálculos sobre los usuarios máximos que deseas y hacer esas estimaciones correctamente.
00:32:40Tenemos, déjame ver... genial.
00:32:55Para el calculador de capacidad, hay un enlace al Colab porque estaba familiarizado con él.
00:33:01Tenía que migrar fuera de toda la biblioteca de widgets y no tenía tiempo.
00:33:16Así que, por pereza, simplemente elegí Colab.
00:33:20Disculpas a mi laboratorio.
00:33:23Así que mi VRAM está conectada.
00:33:34De acuerdo.
00:33:45Probablemente sea el Wi-Fi.
00:33:46De acuerdo, genial.
00:34:02Lo que hemos hecho aquí es recopilar algunas GPUs con sus VRAMs y anchos de banda, operaciones de punto flotante y coste por hora.
00:34:11Luego construimos este sencillo calculador de capacidad.
00:34:19Esto es solo un visualizador de KV donde, al aumentar el número de tokens, ves que el tamaño de KV aumenta.
00:34:29Y cuando aumentas el número de usuarios, el tamaño aumenta a un ritmo mucho más rápido.
00:34:37Y luego, en este calculador de capacidad, vamos a dejarlo correr.
00:34:47Tenemos un modelo de 7 mil millones de parámetros que seleccionamos.
00:34:56Establecemos la precisión en FP16.
00:35:01Ahora decidimos, la forma en que tomamos la decisión sobre la GPU es fijar primero una dimensión que sea la que más te importe.
00:35:15Para el chat prémium, mencioné que la latencia es definitivamente esa.
00:35:21Y para las cargas de trabajo asíncronas, el tamaño mínimo de lote que deseas resolver con una sola GPU es la segunda dimensión.
00:35:31Por lo tanto, primero hay que fijar esto.
00:35:34Por lo tanto, abordaré esto como una aplicación de chat prémium.
00:35:39Puedo avanzar con una latencia de 10 milisegundos.
00:35:44Un tamaño de lote mínimo, no me importa.
00:35:46O sea, estoy bien con probablemente dos.
00:35:53De acuerdo.
00:35:54Entonces, probablemente con siete usuarios concurrentes en una sola GPU.
00:35:59Y mi límite de contexto es muy importante para mí porque también quiero centrarme en la calidad.
00:36:07Y veo algunas de las GPUs.
00:36:10La H100 de 80 GB cuesta unos 8 dólares por hora.
00:36:15Pero, ¿y mi RTX 3090?
00:36:19¿Es así?
00:36:20Sí.
00:36:21Así que ronda los 10 dólares por hora.
00:36:24Así que, si hacen todo ese cálculo de rendimiento que compartimos antes en las matemáticas, podrían calcular su costo por millón de tokens.
00:36:34Eso podría ser muy, muy, podría ser menor.
00:36:37Por lo tanto, deben hacer esos cálculos fijando esas dimensiones y deben decidir su GPU para reducir su tipo de costos de inferencia.
00:36:49Así que este es al menos el primer paso que pueden dar hacia la optimización de la inferencia.
00:36:56De acuerdo.
00:37:01Bien, la siguiente diapositiva.
00:37:04Déjeme...
00:37:08De acuerdo, genial.
00:37:10Y ahora lo siguiente trata sobre la optimización del modelo.
00:37:15Así que ahora básicamente hemos construido esa base en la que entendimos algunos de los puntos débiles, la razón detrás de ellos y por qué ocurrían.
00:37:23Cómo podríamos abordar ese problema de la capacidad de la GPU.
00:37:29Necesitamos entender qué podemos hacer, qué más podemos hacer al respecto.
00:37:33Se trata de la optimización del modelo y creo que me gustaría invitar a Tanmay.
00:37:39Él puede hablar más sobre estas optimizaciones de modelos, dado que ha trabajado en esto durante sus tiempos de investigación.
00:37:47Bien.
00:37:48De acuerdo.
00:37:49Puedo controlar.
00:37:50Puedo controlar.
00:37:54Sí.
00:37:55Aquí.
00:37:56Bien.
00:37:57Hola a todos.
00:37:58Prueba de micrófono.
00:37:59¿Se me escucha por fin?
00:38:00Sí.
00:38:01De acuerdo.
00:38:02Hola.
00:38:03Soy Tanmay Shah.
00:38:04Trabajo como modelador cuantitativo sénior y también soy investigador de IA.
00:38:08Por lo tanto, me centro en la verificación de agentes y actualmente en la construcción de modelos del mundo.
00:38:13Así que, para este tema, la optimización de modelos.
00:38:16Antes de comenzar con la optimización de modelos, creé una plantilla de investigación para que nos sea más fácil entender todas estas cosas complejas.
00:38:25Nuestra plantilla es sencilla.
00:38:28Primero, identificaremos el problema.
00:38:30Segundo paso, resolveremos el problema utilizando dos algoritmos.
00:38:34Estos son solo algoritmos ficticios.
00:38:35El primer algoritmo se llama algoritmo del avestruz.
00:38:39Siempre que vemos, al igual que el avestruz, cuando vemos un problema, el avestruz mete la cabeza en la arena.
00:38:46Haremos lo mismo.
00:38:47Cada vez que enfrentemos un problema, simplemente lo ignoraremos.
00:38:51Este es un algoritmo importante que debemos seguir.
00:38:55El segundo fue creado y se llama algoritmo de la copa del mundo.
00:38:59Por ejemplo, no sabemos quién ganará esta Copa Mundial de la FIFA.
00:39:03Así que lo que hicieron los organizadores fue dividir los 48 equipos en 12 grupos.
00:39:11Luego la ronda de 32, así que la ronda de 32 se está jugando actualmente.
00:39:16Luego los octavos de final, los cuartos de final, las semifinales y la final.
00:39:21Lo que están haciendo es dividirlo en problemas más pequeños y los resultados útiles avanzan.
00:39:30Usaremos la misma analogía o el mismo algoritmo para entender esta optimización de modelos y todo lo demás.
00:39:38Así que sí, comencemos.
00:39:41Tengo una GPU H100.
00:39:46Tengo que usar este modelo de código abierto, llamado modelo GPT OSS de 120 mil millones de parámetros.
00:39:54Ahora mismo creo que, lo han entrenado en BF float 16 y el peso es de 240 gigabytes.
00:40:02¿Qué debo hacer?
00:40:04Este es el problema que tenemos.
00:40:07Lo primero que tenemos que hacer es lidiar con 240 gigabytes y una H100 de 80 gigabytes.
00:40:16Y tengo que ajustarlo en una sola GPU, no en varias.
00:40:21¿Qué podemos hacer?
00:40:22Creo que el paso sencillo es simplemente comprimirlo.
00:40:27¿Pero cómo deberíamos comprimirlo?
00:40:29Ese es otro reto.
00:40:30Si comprimimos BF float 16 a FP8, rondará los 120 gigabytes.
00:40:38Pero nuestra GPU H100 sigue siendo de 80 gigabytes.
00:40:42Así que creo que lo que hicieron fue comprimirlo aún más a MXFP4.
00:40:49Y creo que el tamaño es de unos 65 gigabytes.
00:40:53Esto es algo que podemos hacer, comprimir, pero surge una pregunta.
00:40:59Y usaremos nuestro algoritmo del avestruz.
00:41:03Asumimos que no hay pérdida al comprimir un modelo más grande en un tamaño menor.
00:41:10Lo segundo, en este caso, de acuerdo, sí.
00:41:16En esta diapositiva hemos usado este Mistral 7B.
00:41:20Es decir, siete mil millones de parámetros.
00:41:22Es un modelo pequeño, de siete mil millones de parámetros.
00:41:25Si lo multiplicas por dos bytes, su peso es de alrededor de 14.
00:41:3114.5 gigabytes, que caben fácilmente en una H100 o incluso en una A40.
00:41:38Lo siguiente que podemos hacer con Mistral 7B, en vez de comprimirlo a coma flotante 16, es aplicar diferentes técnicas como int8, int4 o nf4.
00:41:53Básicamente, tenemos que usar el algoritmo del avestruz y simplemente creer que no hay pérdida de calidad.
00:42:01Pero, de algún modo, también tenemos que demostrarlo matemáticamente haciendo pruebas en algún benchmark externo para ver si funciona o no.
00:42:10Esto entra dentro del ámbito de la cuantización posterior al entrenamiento.
00:42:16También se puede hacer durante el ajuste fino.
00:42:20Uno también puede hacer este tipo de cuantización.
00:42:22Esto entra dentro de lo que se conoce como entrenamiento consciente de la cuantización.
00:42:25Pasemos a nuestro siguiente problema.
00:42:31Tenemos estas enormes matrices.
00:42:37Imaginen una dimensión de 1000 por 1000, matriz A, y otra matriz de 1000 por 1000.
00:42:51Si multiplican estas dos matrices, el número de operaciones será 1000 elevado al cubo.
00:43:00Y esto es un problema en términos de computación.
00:43:06Por lo tanto, queríamos que nuestra multiplicación de matrices fuera rápida y ahorrara memoria.
00:43:13¿Qué deberíamos hacer?
00:43:15Tenemos una matriz gigante.
00:43:17De acuerdo, tomemos esta, de 4096 por 4096.
00:43:23¿Qué deberíamos hacer para resolver nuestro problema de acelerar las cosas y ahorrar memoria con 4096 por 4096?
00:43:33Entonces, lo primero es que usaremos nuestro algoritmo World Cup.
00:43:37Podemos decidir un número aleatorio, romper el bloque verticalmente.
00:43:42No importa lo que elijan.
00:43:45Digamos que tenemos 4096 columnas.
00:43:51Las dividiremos en grupos de 128 columnas cada uno.
00:43:57Así que 128, 128, 128, 128, 128 verticalmente.
00:44:03Obtendremos estos 32 bloques si dividimos este 4096.
00:44:09Entonces, ¿qué pasará al hacer esto?
00:44:13Si simplemente dividimos este de forma vertical, podemos usar múltiples GPUs para acelerar el proceso.
00:44:21Este tipo de cosas se llama atención multi-cabeza.
00:44:26¿Qué más podemos hacer?
00:44:29Tenemos una matriz grande como, mencioné antes, el algoritmo del avestruz.
00:44:36Nuestro problema principal es el tamaño.
00:44:39Lo que podemos hacer en lugar de tener esos 32 bloques verticales es descartar 31 bloques.
00:44:49Y asumiremos que un bloque es lo suficientemente suficiente como para que todas las consultas puedan manejar esos bloques.
00:44:57Nuestra pérdida será casi insignificante.
00:45:00Y se nos ocurre este algoritmo.
00:45:04Este algoritmo se llama atención de consulta múltiple.
00:45:08Como podemos ver, ahora mismo estamos en dos extremos.
00:45:12Uno es la atención multi-cabeza, donde lo dividimos en 32 bloques y usamos diferentes GPUs o hacemos procesamiento en paralelo.
00:45:22Y al mismo tiempo, simplemente estamos descartando 31 bloques.
00:45:26Y a esto lo llamamos atención de consulta múltiple.
00:45:31Así que, en ambos extremos, deberíamos encontrar un punto medio.
00:45:38Podemos decir que, en lugar de descartar los 31, tal vez podamos agrupar algunos de los bloques.
00:45:49Y podemos asumir que bloques similares atenderán a un tipo similar de consultas.
00:45:58Este tipo de técnica entra dentro de la atención de consulta agrupada, que es muy popular ahora mismo.
00:46:04Incluso en Mistral o en otros modelos, esta atención de consulta agrupada funciona.
00:46:11Así que ahora hemos entendido que tenemos una matriz grande.
00:46:16Podemos dividirla como queramos y haciendo algún cálculo matemático,
00:46:19probar que la pérdida es casi insignificante.
00:46:23¿Qué más podemos hacer?
00:46:25Después de eso, después de esta atención de consulta agrupada,
00:46:34vean, tenemos una matriz grande.
00:46:38Una es la clave y la otra es el valor.
00:46:42Comprimamos esa matriz en un vector latente.
00:46:47Y luego idear algún algoritmo para reconstruir desde el vector latente hasta nuestra matriz original.
00:46:55Este tipo de estrategia entra dentro de esta categoría.
00:46:59Atención latente multi-cabeza.
00:47:02Pero de nuevo, tiene algunos problemas con RoPE porque RoPE depende de la posición y esto es independiente de la posición.
00:47:10Así que también es necesario incluir algún índice para las claves para poder mapearlas.
00:47:16Pero de nuevo, el problema principal es por qué estamos multiplicando todas esas matrices grandes.
00:47:25Porque así es como funciona este mecanismo de atención, que cada token prestará atención a todos los tokens.
00:47:33Entonces, ¿qué tal si no prestamos atención a todos los tokens anteriores, sino solo a los tokens importantes para nosotros?
00:47:42Por lo tanto, este tipo de campo está evolucionando.
00:47:46Esto entra dentro de la atención dispersa de DeepSeek.
00:47:51Así que sí.
00:47:53Y, bueno, entonces, de acuerdo.
00:47:56Siguiente.
00:47:59Sí, el siguiente es la atención Flash.
00:48:02En la atención Flash, el problema principal es que,
00:48:09actualmente, bueno, no actualmente, ahora mismo casi todo el mundo usa la atención Flash, pero allá por 2022 o 2023...
00:48:20Así es como funciona.
00:48:23La forma en que funciona es que estas matrices Q y K, de consulta y clave, estaban en la memoria HBM.
00:48:34Se cargan primero en nuestro núcleo tensorial, realizan algunos cálculos y luego se vuelven a escribir en la memoria HBM.
00:48:47Y este proceso se repite múltiples veces.
00:48:51Entonces, en la atención Flash, lo que hicieron en lugar de multiplicar matrices enteras...
00:48:59fue dividirlas, como en el algoritmo World Cup, dividiendo las matrices grandes en pequeños bloques,
00:49:05y colocando solo esos bloques pequeños en una memoria SBM para procesar la multiplicación rápidamente,
00:49:13y manteniendo un registro de tres variables para poder calcular esta función softmax en línea.
00:49:20Sí, esto es solo matemáticas; si tenemos atención multi-cabezal para 524 kV,
00:49:34entonces depende de cuánta agrupación queramos; si en lugar de 32 cabezales kV solo queremos usar 8 cabezales kV,
00:49:47podemos obtener una compresión de 4x con esta atención de espacio latente multi-cabezal.
00:49:54Esta fórmula depende de cada modelo, según cuántas capas tenga.
00:50:00En el artículo original de DeepSeek, creo que usaban alguna dimensión de 128... no recuerdo la dimensión exacta, pero según eso,
00:50:11utilizaron este vector latente, en el cual usaron 512 como dimensión y unos 64 para el índice RoPE,
00:50:23y luego demostraron que está 56 veces más comprimido que la atención multi-cabezal.
00:50:32De acuerdo.
00:50:33Sí, este es el diagrama de compensaciones; aquí creo que no hemos hablado de la atención lineal ni de Mamba.
00:50:50El problema principal son todas estas multiplicaciones de matrices; ahora mismo todo el mundo usa la atención.
00:50:56Supongamos que en el futuro no queremos usar la atención, y en lugar de generar tokens secuencialmente, usamos modelos de difusión,
00:51:07donde podemos generar todo simultáneamente; entonces todos estos algoritmos también cambiarán.
00:51:14Pero aquí creo que tienen dos más: la atención lineal y Mamba.
00:51:19Según esta diapositiva, si no estamos comprimiendo nada, la MHA simplemente paraliza el proceso.
00:51:29Así que no hay pérdida de calidad, lo cual es bueno, y luego está la atención de consultas agrupadas, que creo que casi todos los modelos usan, como GQA y DSA.
00:51:42Sí.
00:51:43Creo que lo mismo ofrecemos en la tabla de puntuación del mecanismo de atención: la calidad de MHA es buena, el rendimiento es aceptable.
00:51:56Y para la atención de consultas agrupadas, depende de su caso de uso; aunque la calidad es casi similar a la atención multi-cabezal, el caso de uso también importa mucho.
00:52:10Sí, la atención de consulta única es un extremo.
00:52:13Asumimos, no sé por qué, que solo necesitamos un bloque y todas las consultas atenderán a esos bloques más pequeños.
00:52:24Así que la calidad no es tan grandiosa para la MQA.
00:52:29Y respecto a la atención latente multi-cabezal, si han probado los modelos DeepSeek, creo que están haciendo un gran trabajo en cuanto a calidad, además de la ventana deslizante.
00:52:44Todas estas son técnicas, como ajustar las ventanas; en lugar de multiplicar todo, la atención lineal dice: resume todo primero y luego búscalo. Y Mamba es simplemente un modelo de espacio de estados.
00:53:09Para las optimizaciones de modelos, también tenemos un par de cuadernos aquí.
00:53:28Tengo que ir a esto.
00:53:35Bien, para la cuantización, como en la demo, ¿esto ya se ejecutó? No.
00:53:51Déjenme ejecutar esto.
00:53:54Bien, estamos cargando el modelo, que es como Mistral 7B.
00:54:10Este es con la línea base FP16.
00:54:20Espera.
00:54:21¿Se ejecutó?
00:54:21Espera.
00:54:22¿Se ejecutó?
00:54:23De acuerdo.
00:54:24Tomó dos milisegundos en ejecutarse.
00:54:27¿Se ejecutó esto?
00:54:28De acuerdo.
00:54:29Esta vez está obteniendo el modelo con precisión FP16.
00:54:35De acuerdo.
00:54:36Tomó dos milisegundos en ejecutarse.
00:54:40¿Se ejecutó esto?
00:54:41De acuerdo.
00:54:42Esta vez está obteniendo el modelo con precisión FP16.
00:54:47El Wi-Fi.
00:54:58Va a tomar tiempo.
00:55:03De acuerdo.
00:55:08Sí, porque está descargando los pesos desde Hugging Face.
00:55:14¿Eh?
00:55:17Colab se está ejecutando en línea.
00:55:22Sí.
00:55:23Porque necesita hacer la llamada de red a través de Hugging Face y realizar la recuperación.
00:55:30No sé, pero probablemente está tardando en descargar.
00:55:35De acuerdo.
00:55:36De acuerdo.
00:55:37De acuerdo.
00:55:38De acuerdo.
00:55:39De acuerdo.
00:55:40Aquí vemos que el tamaño de la memoria es de unos 15 GB aproximadamente con la precisión FP16.
00:56:00Estamos intentando hacer la compresión de 2x, como habló Talmud, con int8.
00:56:15De acuerdo.
00:56:16Vemos que el tamaño de la memoria ahora es de 0.7, 0.5 GB.
00:56:21Lo que significa que ahora tienes más memoria para que tu caché KV pueda crecer.
00:56:27Eso significa que puedes admitir un límite de contexto mayor o puedes admitir a más usuarios concurrentes.
00:56:36Si usas int4, básicamente estás haciendo una compresión de 4x.
00:56:41Con la compresión de 4x, sería aún menor.
00:56:45Creo que rondaría entre 3 y 4 GB.
00:56:50Sí, 4.5 GB.
00:56:51Y eso es todo, espera.
00:56:52Esto es... espera.
00:56:53Este es solo un gráfico básico de números teóricos.
00:57:09No estamos realizando ninguna prueba de rendimiento aquí.
00:57:12Pero por lo general, verás que tu memoria aumenta.
00:57:15Así que también obtendrás un rendimiento ligeramente mayor.
00:57:21A partir de algunas de las pruebas que estudiamos, vimos que la compresión int8
00:57:26sí tiene un rendimiento menor.
00:57:32De acuerdo.
00:57:33Y luego hay una demostración sobre los mecanismos de atención.
00:57:42Sobre la atención, bien.
00:57:45Tengo que ejecutar esto.
00:57:58De acuerdo.
00:57:59Ya se ejecutó.
00:58:02Oh.
00:58:03Espera.
00:58:04¿Por qué dice que no se detectó ninguna GPU?
00:58:09Debería decir que se detectó la GPU.
00:58:18Oh.
00:58:19De acuerdo.
00:58:29Espera.
00:58:30Espera.
00:58:30Espera.
00:58:50Esto es sorprendente.
00:58:57Supongo que no puede detectar la GPU por alguna razón.
00:59:05Sí tenemos una GPU aquí.
00:59:11De acuerdo.
00:59:12No importa.
00:59:14Sí.
00:59:14Pero la idea básica aquí era más bien que al intentar avanzar hacia la compresión del cálculo mediante diferentes mecanismos de atención,
00:59:26como pasar de multi-cabezal a atención de consultas agrupadas y luego a MLA,
00:59:33comenzarás a ver algunas optimizaciones.
00:59:38Creo que anoche estábamos haciendo algunas pruebas de rendimiento.
00:59:43Quería corregir esta parte.
00:59:45No era de 56x.
00:59:48Era de 14x.
00:59:50Básicamente, la demo tenía un error de cálculo en el que no multiplicó el número de capas.
01:00:02Sí.
01:00:03Así que disculpas por eso.
01:00:04Este MLA ofrece un ahorro de 14x en comparación con la atención multi-cabezal.
01:00:15Ahora que entendemos los puntos débiles, los cimientos y una parte de las optimizaciones, que son las de los modelos, queremos hablar de lo que se puede hacer en el lado del servicio.
01:00:31Lo primero que vimos es que, al realizar un simple paso de decodificación, básicamente extraes los pesos del modelo y luego vuelves a calcular los vectores de clave y valor para todos los tokens anteriores,
01:00:50a pesar de que ya habías calculado esos vectores para todos los tokens.
01:00:55Por lo tanto, definitivamente hay un gran desperdicio de cómputo.
01:01:02Si analizas su complejidad temporal, resulta ser O de N al cuadrado.
01:01:07Y la forma de resolverlo es mediante una compensación clásica con la memoria.
01:01:12Puedes mantener una memoria de esos vectores asociada a los tokens y hacer referencia a esa memoria.
01:01:19Esa memoria se denominó caché KV.
01:01:24El flujo se ve más o menos así.
01:01:27A partir de este caché KV, realmente eran posibles cuatro optimizaciones.
01:01:35La primera trata sobre la atención paginada.
01:01:42¿Cuál es la diferencia? ¿Cuál es el problema hoy en día?
01:01:45Por lo tanto, cuando envías varias solicitudes como entrada a la GPU, estas solicitudes están en un lote.
01:01:52A cada solicitud se le asigna un almacenamiento de memoria continuo.
01:01:58Digamos de, solo por dar un ejemplo, digamos, 2 KV.
01:02:05Sin embargo, tu solicitud solo necesitaba, digamos, 1 KV.
01:02:11Por lo tanto, hay una fragmentación de esa memoria de alrededor del 50%.
01:02:19Y esta fragmentación básicamente conduce al desperdicio de memoria.
01:02:24Eso significa que había espacio en la memoria donde podrías haber atendido más solicitudes, pero no pudiste porque estabas buscando ese bloque contiguo de memoria.
01:02:36Así que se tomó inspiración de cómo funciona el sistema operativo.
01:02:41Por ejemplo, mantienes una memoria lógica y básicamente tienes una memoria física.
01:02:47Entonces, en la memoria lógica, todavía parecería que el vector KV para cada token es contiguo.
01:02:59Pero se estará mapeando a una dirección física diferente.
01:03:06Así que eso realmente ayudó a ahorrar mucha memoria.
01:03:11Y solo fue posible porque consideran la memoria como un conjunto de bloques.
01:03:18Y asignarías esos bloques dinámicamente según las necesidades de las solicitudes.
01:03:22A medida que llegan nuevos tokens y necesitan ese tipo de memoria.
01:03:27Otra palanca es cuando envías múltiples solicitudes en el lote,
01:03:39la GPU toma esas solicitudes.
01:03:42Pero no acepta el nuevo lote a menos que todas las solicitudes de ese lote se completen.
01:03:49Por lo tanto, el diagrama se parece más a la atención paginada.
01:03:52Pero aquí se trata más de cuándo está disponible la GPU para tomar el siguiente lote.
01:03:59Así que hay un periodo de tiempo en el que la GPU se queda realmente inactiva.
01:04:04Y quieres resolver eso.
01:04:08Y para eso, la idea fue, de acuerdo, hagamos ese procesamiento por lotes continuo.
01:04:17Por lo tanto, el procesamiento por lotes continuo también ayudó mucho con el rendimiento, porque ahora puedes enviar más solicitudes con bastante rapidez.
01:04:24Asegurándote de que la GPU esté siempre ocupada y no se quede inactiva.
01:04:33De este modo, te ahorras ese cómputo.
01:04:36El tercero es el almacenamiento en caché de prefijos.
01:04:39Recuerdas que la caché KV te ayudó a ahorrar el cálculo para una sola solicitud a través de los tokens.
01:04:46¿Pero qué pasa si tienes los mismos tokens en múltiples solicitudes?
01:04:53¿Cómo te ahorras eso?
01:04:55Por lo tanto, el almacenamiento en caché de prefijos, introducido por VLLM, contrarresta exactamente eso.
01:05:04Y luego el tercero es, bueno, hablamos del cuarto, en realidad.
01:05:10Hablamos de cuantizar el modelo, pero también puedes cuantizar los pesos KV.
01:05:21Eso significa que ahora necesitas menos espacio para tus vectores de clave y valor.
01:05:28Esto significa que puedes alojar más vectores de clave y valor en la memoria.
01:05:32Y eso significa que puedes servir más tokens.
01:05:34Lo que significa que puedes ofrecer un mayor límite de contexto.
01:05:37Y eso significa que puedes ofrecer una mejor calidad de modelo.
01:05:41Y todo esto ya está presente en VLLM.
01:05:51Realmente no necesitas reinventar la rueda.
01:05:56Y puedes implementar este VLLM en producción y verás ese crecimiento.
01:06:03A continuación, tenemos una prueba de rendimiento que realizamos.
01:06:08Esta prueba, déjenme ver si la tengo por aquí.
01:06:14Aquí.
01:06:17Las demostraciones.
01:06:22Hacer esta prueba toma alrededor de una hora porque tienes que detener y reiniciar continuamente los servidores VLLM, cargar los modelos y todo eso.
01:06:35Así que toma bastante tiempo hacer las pruebas, pero realmente puedo explicarles aquí lo que estamos haciendo.
01:06:41Hemos mantenido el modelo igual, como el Mistral 7B.
01:06:46Y luego tenemos el conjunto de preguntas de entrada que estamos enviando.
01:06:53Considérenlos como los prompts.
01:06:56Luego tenemos un par de funciones auxiliares aquí, como comprobar si el servidor está activo o no.
01:07:01Este servidor es el servidor VLLM.
01:07:04Luego hay funciones auxiliares para obtener las métricas de VLLM.
01:07:09Y hablaré sobre cuáles son esas métricas.
01:07:14Después hay muchas pruebas de rendimiento y todo eso.
01:07:17Y luego tienes que medir el uso de KV y demás.
01:07:22Estas son las funciones auxiliares.
01:07:24La línea base es muy sencilla.
01:07:26Tenemos una línea base de Hugging Face.
01:07:29Esto es enviar texto al LLM de forma directa y obtener la respuesta.
01:07:36Vemos algunos resultados aquí.
01:07:38Vimos que Hugging Face tiene un rendimiento de alrededor de 51 tokens por segundo.
01:07:44El tiempo hasta el primer token fue de 54.
01:07:46Y la latencia entre tokens fue de 19.
01:07:49Todo esto se ejecutó en la H100.
01:07:56Y luego iniciamos un servidor VLLM predeterminado.
01:08:00Por defecto, VLLM te proporciona atención paginada, procesamiento por lotes continuo y almacenamiento en caché KV.
01:08:08Así que esas tres cosas están presentes por defecto.
01:08:13Y al comparar esas pruebas de rendimiento, ves que tu rendimiento es casi 15 veces mayor.
01:08:21Puedes procesar más tokens por segundo.
01:08:24Luego, tu tiempo hasta el primer token también aumenta.
01:08:34Y la latencia entre tokens disminuye.
01:08:38Y tu uso de KV frente a los usuarios y frente al contexto aumenta, por supuesto.
01:08:43Ahora, cuando le aplicas el almacenamiento en caché de prefijos.
01:08:51Con el almacenamiento en caché de prefijos, ves que tu rendimiento aumenta aún más.
01:08:57Tu TTFT disminuye.
01:08:59Tu latencia entre tokens es aproximadamente la misma.
01:09:02Y el uso de la caché KV frente a los usuarios tiende a disminuir.
01:09:09Frente al contexto, no disminuye.
01:09:12Es aproximadamente el mismo.
01:09:14Creo que esto también es aproximadamente igual.
01:09:16No es para tanto.
01:09:19Cuando aplicas la cuantización KV además de eso.
01:09:25Ves que el rendimiento es casi similar.
01:09:33Tu tiempo hasta el primer token es similar.
01:09:36Tu latencia de tokens es similar.
01:09:39Pero tu uso de KV en realidad se reduce.
01:09:42Esto se debe a que has cuantizado tu espacio de clave-valor.
01:09:49Y luego está el concepto de decodificación especulativa del que hablará Tanmay.
01:09:54Así que, al hacer pruebas de rendimiento con ellos, también se puede ver un uso de KV ligeramente menor.
01:10:06Aunque los resultados son aproximadamente los mismos.
01:10:08Así que sí, en general, estas son las métricas en comparación.
01:10:21Probablemente debería alejar la imagen.
01:10:25De acuerdo.
01:10:26No.
01:10:27Alejar.
01:10:28No funciona.
01:10:29Genial.
01:10:30Así que sí, estas son las pruebas de rendimiento de VLLM.
01:10:35Es tu valor predeterminado para producción, por cierto.
01:10:38También compartiremos ese árbol de decisiones cuando hablemos de los otros motores.
01:10:48Entonces, deberíamos hablar de cuáles son algunas de las otras optimizaciones de inferencia que podemos hacer sobre esto.
01:10:58Y cuáles fueron algunas de las otras soluciones que surgieron.
01:11:02Me gustaría invitar nuevamente a Tanmay.
01:11:07Él va a hablar sobre algunas de estas optimizaciones.
01:11:11Oh, lo siento.
01:11:12Lo siento mucho.
01:11:13No activé las diapositivas.
01:11:26¿Cuál era?
01:11:27De acuerdo.
01:11:28Genial.
01:11:29Perfecto.
01:11:30¿Cuál?
01:11:31La decodificación especulativa.
01:11:32Sí.
01:11:33Gracias, Harshal.
01:11:34Sí.
01:11:35Todo esto es decodificación especulativa.
01:11:40Todo esto son, como decimos, diferentes sabores del mismo refresco.
01:11:46Esta técnica pertenece a los aceleradores de decodificación.
01:11:51Primero, solo hablamos de esta decodificación especulativa, pero hay otras variantes, como autoespeculativa, Eagle, Medusa.
01:12:01Solo me gusta, creo, esta, el algoritmo Eagle.
01:12:05Comencemos con la decodificación especulativa.
01:12:06De acuerdo.
01:12:07De acuerdo.
01:12:08Empecemos por qué es la decodificación especulativa.
01:12:09El problema principal es que en la arquitectura transformer, todos estos tokens se generan secuencialmente, uno por uno por uno.
01:12:26¿Qué tal si simplemente usamos un modelo más pequeño y dejamos que genere tal vez cuatro o cinco tokens?
01:12:37Y este modelo profesor, o podríamos decir, según nuestro algoritmo del Mundial, podemos decir árbitro.
01:12:43El árbitro decidirá cuántos tokens acepta.
01:12:48Y este bucle continúa.
01:12:51Nuestra suposición es que hay ciertos dominios donde este tipo de cosas funcionan.
01:12:59Tal vez en programación, donde casi no hay creatividad.
01:13:05Cada código o sintaxis es casi similar.
01:13:08Así que tal vez pueda ayudar.
01:13:10Pero, según mis pruebas personales, esta decodificación especulativa no me pareció útil en absoluto.
01:13:18Pero otras técnicas, como la autodecodyficación especulativa, donde el modelo profesor también tiene una cabeza auxiliar, y hace algo similar a lo que hace este modelo base o modelo pequeño.
01:13:35Pero luego llegó esto, EGLE, EGLE 1, 2, 3, no sé cuántas versiones hay, pero solo dice que en lugar de crear, en lugar de generar tokens, entrenemos un modelo pequeño y tomemos características de una de las capas principales de los modelos para que, en lugar de generar tokens, genere esta característica.
01:14:02Por lo tanto, EGLE es mejor en comparación con este otro tipo de tecnologías.
01:14:10Y luego otro es MEDUSA, que simplemente dice que generes todos estos tokens en paralelo.
01:14:17Muy bien, entonces aquí, aquí en esta diapositiva.
01:14:21Sí.
01:14:22La siguiente diapositiva.
01:14:24Bien.
01:14:25Bien.
01:14:26De acuerdo, sí.
01:14:27Bien.
01:14:28Ahora pasamos a, ahora llegaremos a este de almacenamiento en caché de prefijos.
01:14:34Entonces, no sé si la gente está usando este almacenamiento en caché de prefijos estáticos o no.
01:14:39Pero el caso es que el principal problema con el almacenamiento en caché de prefijos es que a veces escribimos y cometemos un pequeño error.
01:14:47Y este almacenamiento en caché de prefijos estáticos estándar básicamente toma un mensaje y hace un hash.
01:14:53Y la próxima vez que el usuario haga una pregunta similar, intentará hacer coincidir el hash.
01:14:58Entonces, si el hash es igual, en lugar de volver a computar toda esa K y V, simplemente lo tomará del almacenamiento.
01:15:09Pero ya sabes que a veces cometemos un error o tal vez podemos cambiar una palabra o letra, algo así.
01:15:15Entonces tenemos una tasa de fallos de caché mucho mayor.
01:15:21Por eso este, el árbol Radix.
01:15:25Así que el árbol Radix se está volviendo muy popular y también debido a los agentes.
01:15:30Así que creo que casi todo el mundo está haciendo agentes y la mayor parte del cálculo ocurre durante el tiempo de prueba, algo así como la inferencia.
01:15:38Donde seguimos haciendo las mismas preguntas y avisos.
01:15:42Por ejemplo, eres un ingeniero de software experto multiplicado por 200 veces.
01:15:48Este tipo de bucle sigue ocurriendo dentro de este tipo de cosas agénticas.
01:15:55Donde es necesario conservar o almacenar cosas similares en un árbol Radix.
01:16:03Por lo tanto, el árbol Radix es solo una versión avanzada de este árbol de prefijos donde simplemente colapsaremos un nodo si no tiene ninguna rama.
01:16:17Y para este tipo de trabajo en el que seguimos repitiendo lo mismo.
01:16:24Este árbol Radix ayuda mucho y sglang utiliza este tipo de algoritmo para el almacenamiento en caché de prefijos.
01:16:35De acuerdo, sí, luego hay otra cosa.
01:16:38Uno es Tensor RT-LLM.
01:16:41Esto es muy confuso.
01:16:42Cuando empecé, estaba simplemente confundido.
01:16:46¿Qué es Tensor RT-LLM?
01:16:49Así que, sí, Tensor RT es solo un SDK estándar, por así decirlo.
01:16:55Tensor RT-LLM es solo un motor de inferencia.
01:16:59Igual que vLLM, sglang.
01:17:01Pero el problema es que está relacionado con NVIDIA.
01:17:05Optimizaron cada una de las capas y cada problema.
01:17:10Como mencioné en nuestro algoritmo del Mundial, simplemente descomponen todo y optimizan todo también a nivel de hardware.
01:17:18Así que, de acuerdo, siguiente.
01:17:23Sí, para este taller también hicimos algunas pruebas comparativas para ver cuál es mejor.
01:17:33Nuestra configuración fue algo similar.
01:17:36Así que hicimos dos tipos de pruebas.
01:17:39La primera es sin pruebas agénticas, donde simplemente...
01:17:44Entonces usamos ShareGPT, este conjunto de datos, y simplemente hicimos esas preguntas usando vLLM y sglang.
01:17:57Bien.
01:18:05Sí, de acuerdo.
01:18:07Y déjenme acercar la imagen.
01:18:12Muy bien, genial.
01:18:13Muy bien, para este taller usamos H100, y nuestra primera prueba consistió en que simplemente preguntamos...
01:18:23Tomamos preguntas de ShareGPT y las pusimos en vLLM y sglang, y descubrimos que en realidad no hay diferencia estadística sobre cuál es mejor.
01:18:34Por lo tanto, ambos tienen un tipo casi similar...
01:18:37Así que ambos están cumpliendo con un tipo de solicitudes por segundo, TTFT y latencia similares.
01:18:43Sin embargo, la única diferencia que hemos visto ocurre durante la ramificación agéntica.
01:18:50Entonces, lo que hicimos fue hacer una pregunta similar, como que eres el mejor ingeniero de software del mundo.
01:18:59Así que resuelve el problema de la congestión del tráfico en la ciudad, por ejemplo.
01:19:04Luego introdujimos esto en el LLM.
01:19:08El LLM genera algún resultado.
01:19:10Luego hicimos una segunda ronda también.
01:19:13Entonces, una vez que este LLM genera este resultado, en la segunda ronda mencionamos específicamente que...
01:19:22proporcionaras, revisaras la propuesta y otorgaras calificaciones del uno al diez.
01:19:28Estos son los dos turnos que hicimos, y este bucle se sigue repitiendo.
01:19:35Lo que descubrimos es que para este tipo de flujo de trabajo donde todo es estándar, entran en juego todos esos prompts y la ingeniería de contexto.
01:19:47Por lo tanto, si realizamos esta ramificación agéntica de forma adecuada, creo que este SGLang es de tres a cuatro veces mejor.
01:19:54Pero, de nuevo, esto depende de las diferentes configuraciones tal vez.
01:19:58Si lo haces, puedes obtener resultados diferentes.
01:20:02De acuerdo.
01:20:03Sí.
01:20:04Así que creo...
01:20:06¿Lo subimos a GitHub?
01:20:08Sí.
01:20:09Bien.
01:20:10Sí.
01:20:11Así que el PDF también está en el Drive.
01:20:15Es el mismo enlace que el de las diapositivas.
01:20:18Así que un resumen rápido por aquí.
01:20:22Por lo tanto, en cuanto al rendimiento de una carga de trabajo de API estándar, verías que vLLM y SGLang son iguales.
01:20:31Entonces, si no tienes...
01:20:33Si tienes una carga de trabajo estándar, ve definitivamente con vLLM.
01:20:36Es el valor predeterminado para producción de todos modos.
01:20:38Pero lo que Tanmay también decía es que cuando intentas crear cargas de trabajo de tipo agéntico, es ahí donde realmente brilla SGLang.
01:20:50Y te proporciona por así decirlo todos los beneficios.
01:20:55Así que, sí.
01:20:58Mantén vLLM como valor predeterminado.
01:21:00Pero si tienes cargas de trabajo agénticas, intenta probablemente migrar hacia SGLang.
01:21:05Si no estás satisfecho con la parte de vLLM.
01:21:09Bien.
01:21:10Déjame...
01:21:15Espera.
01:21:18De acuerdo.
01:21:21Y luego hay como...
01:21:29Como una comparación que se hace con los 120 mil millones.
01:21:33Como para GPT OSS de 120 mil millones.
01:21:36Esta es una prueba comparativa preparada por PlayPy.
01:21:42Así que hay un enlace a un blog por aquí.
01:21:46Oh, qué bien.
01:21:48De acuerdo.
01:21:49Sí.
01:21:50Entonces hicieron una prueba comparativa similar e incluyeron TensorRT-LLM en ella.
01:21:57Definitivamente, siempre puedes revisar estas pruebas comparativas e intentar entender cuál se adapta mejor a tu caso de uso.
01:22:05Como mencionamos sobre TensorRT, intentan optimizar el lado del hardware también, obteniendo el máximo rendimiento de este.
01:22:16Y luego, en términos de elegir tus motores, una vez que te decides entre vLLM, SGLang, TensorRT, hay algunos motores nuevos que están surgiendo.
01:22:29NVIDIA Dynamo por supuesto.
01:22:43Así que también son para el enrutamiento de sesiones agénticas.
01:22:49Hugging Face siempre está ahí.
01:22:51Es un simple paso.
01:22:53Luego hay un motor MSTAR que fue propuesto recientemente por Stanford.
01:23:00NVIDIA Dynamo para modelos múltiples.
01:23:05Así que definitivamente podrías explorar esos.
01:23:08Y cuando intentas básicamente, solo para dar un resumen rápido, empezamos con una línea base.
01:23:15Intentamos encontrar qué modelo podría ajustarse a nuestros casos de uso.
01:23:22Por lo tanto, podrías elegir un DeepSeek.
01:23:27Podrías elegir un, no elijas Mistral 7B.
01:23:30Es decir, no es bueno.
01:23:32Pero bueno.
01:23:35Así que eliges tu modelo y quieres tener una memoria más pequeña y tratar de ajustar ese modelo más grande en una memoria más pequeña.
01:23:44Para que puedas ahorrar costos en los gastos de GPU.
01:23:47Así que puedes hacer toda esa cuantización.
01:23:51Luego puedes aplicar todas esas optimizaciones de servicio utilizando el motor de servicio adecuado bajo el capó.
01:23:58Por lo tanto, eso realmente puede proporcionarte el rendimiento que tanto deseas.
01:24:07Y ahora, algo que puedes hacer después de volver a casa probablemente, ya que no podemos repasar realmente todo el material aquí, es definitivamente leer sobre parte de la información fuente, como diferentes mecanismos de atención, diferentes motores de estos.
01:24:27Como intentar leer las diferentes pruebas comparativas que están presentes en línea también.
01:24:34Y luego, hay muchas guías detalladas o las siguientes fases de esto, que consisten en aprender sobre algunas estrategias de desalojo de caché KV.
01:24:45Por lo tanto, el mundo avanza hacia la creación de un dominio separado de ingeniería de caché KV.
01:24:50Así que querrás entender qué está pasando allí.
01:24:52Por lo tanto, desalojo de KV, compresiones de caché, memorias híbridas.
01:24:57Así que hay muchas soluciones que están surgiendo en torno a eso.
01:25:01Por lo tanto, intenta ceñirte siempre a esos cimientos, a los fundamentos o a los primeros principios.
01:25:08E intenta ver qué solución resuelve básicamente qué problema y si realmente necesitas que se resuelva ese problema para tu caso de uso.
01:25:17Y luego está la inferencia de LLM distribuida, que es un punto de dolor completamente diferente.
01:25:26Probablemente necesitarías un taller de dos horas allí también para repasar todas las funciones internas y hacer toda la práctica.
01:25:40Sí, y esto es algo que estamos intentando proponer para la sesión de AI Engineer en Nueva York, que consiste en profundizar en las secciones avanzadas de la inferencia de LLM.
01:25:51Por lo tanto, este taller estuvo más enfocado al nivel principiante e intermedio.
01:25:55Así que en este formulario tenemos comentarios y también el nivel de interés.
01:26:02Si creen que necesitamos ciertas mejoras en algunas secciones, no duden en dejar sus comentarios.
01:26:09Y si quieren ver este taller en Nueva York, por ejemplo, sientanse totalmente libres de registrar su interés.
01:26:22¿Eh?
01:26:24Ah, ¿cómo es posible?
01:26:27Bum.
01:26:32Déjenme revisar.
01:26:37De acuerdo.
01:26:38¿Eh?
01:26:39Sí.
01:26:40¿La URL funciona verdad?
01:26:41Sí.
01:26:42¿El código QR no?
01:26:43Vale.
01:26:44Probablemente olvidé vincular ambos.
01:26:45Bien.
01:26:46Genial.
01:26:46Sí.
01:26:47Así que, si pueden dar eso.
01:26:49De acuerdo.
01:26:50Genial.
01:26:51Sí.
01:26:52Así que, si pueden dar eso.
01:26:53Vale.
01:26:54Sí.
01:26:55De acuerdo.
01:26:56Genial.
01:26:57Sí.
01:26:58Así que, si pueden dar eso.
01:26:59Déjenme...
01:27:00Bien.
01:27:00De acuerdo.
01:27:01Genial.
01:27:02Sí.
01:27:02Así que, si pueden dar eso.
01:27:03Déjenme...
01:27:04Vale.
01:27:05Con eso estará bien.
01:27:06Y bueno, creo que ya podemos ir concluyendo este taller.
01:27:13Y estoy seguro de que muchos de ustedes tendrán varias preguntas.
01:27:14Así que podemos resolverlas fuera de línea.
01:27:15Podemos reunirnos y charlar sobre esas dudas.
01:27:16Sí.
01:27:17Claro.
01:27:18Seguro.
01:27:19Muchas gracias a todos.
01:27:20Gracias por unirse.
01:27:21Creo que fue realmente...
01:27:22Muchas gracias a todos.
01:27:23Muchas gracias a todos.
01:27:24Gracias por unirse.
01:27:25Muchas gracias a todos.
01:27:26Gracias por unirse.
01:27:27Creo que fue realmente...
01:27:28Ah, está bien.
01:27:29De acuerdo.
01:27:30Con eso estará bien.
01:27:31Y bueno, creo que ya podemos ir concluyendo este taller.
01:27:33Y bueno, creo que ya podemos ir concluyendo este taller.
01:27:36Y estoy seguro de que muchos de ustedes tendrán varias preguntas.
01:27:39Así que podemos resolverlas fuera de línea.
01:27:41Podemos reunirnos y hablar sobre esas dudas.
01:27:42Sí, claro.
01:27:43Muchas gracias a todos.
01:27:44Creo que fue muy significativo y que todos ustedes hayan venido aquí...
01:27:49Muchas gracias.
01:27:50Sí, gracias.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기