Comunicación eficiente y portátil de mezcla de expertos
Una descripción general de la comunicación portátil de Mezcla de Expertos (MoE), centrada en la optimización del paralelismo de GPU y la reducción de la latencia en modelos de IA a gran escala.
Presentamos una biblioteca de código abierto, portátil y de alto rendimiento para la comunicación de Mezcla de Expertos (MoE) que logra un rendimiento 10 veces más rápido en comparación con las primitivas de comunicación estándar de Todos-a-Todos.
Nuestra implementación presenta varias innovaciones técnicas clave que ofrecen una eficiencia superior en la comunicación MoE:
Comunicación iniciada por GPU (IBGDA): Admite la comunicación directa de GPU a NIC, reduciendo significativamente la latencia al evitar la participación de la CPU.
Solapamiento de comunicación y computación: La arquitectura de núcleo dividido con etapas separadas de envío y recepción permite que la computación continúe simultáneamente con las transferencias de red.
El rendimiento de nodo único más rápido: latencia 2,5 veces menor que la implementación más rápida anterior en configuraciones de un solo nodo.
Rendimiento eficiente y portátil de múltiples nodos: Nuestra implementación logra velocidades hasta 10 veces más rápidas que la comunicación estándar de todos a todos. Aunque es aproximadamente 2 veces más lenta que las implementaciones altamente especializadas, nuestro enfoque ofrece una mejor portabilidad entre versiones de NVSHMEM y entornos de red (NVLink, CX-7 y EFA).
La biblioteca es completamente de código abierto y está disponible en https://github.com/ppl-ai/pplx-kernels.
En este artículo, exploramos los desafíos del paralelismo de expertos en modelos MoE a gran escala y describimos nuestro enfoque para el despacho eficiente de tokens y su combinación en entornos de GPU distribuidos.
Introducción
Los modelos de Mezcla de Expertos (MoE), como DeepSeek R1 y Mixtral 8x7B, mejoran los modelos densos al limitar la cantidad de pesos que se activan para cada token. En lugar de lograr una gran cantidad de parámetros aumentando el número de capas o el tamaño de las capas lineales en el Perceptrón Multicapa (MLP) de cada capa de decodificador, los modelos MoE reemplazan el MLP tradicional con múltiples expertos y un enrutador. Por ejemplo, de los 671B de parámetros de DeepSeek R1, solo 37B se multiplican con un token dado durante la inferencia. Esto reduce en gran medida la cantidad de computación necesaria para decodificar un token y mejora la latencia en comparación con un modelo denso.
Los modelos MoE presentan algunos desafíos adicionales para la inferencia, en comparación con los modelos densos. Si bien los expertos son pequeñas capas MLP, cada capa de decodificador incluye un enrutador que decide a qué expertos se envía un token, siendo cada token enviado a múltiples expertos. El enrutador es típicamente una pequeña capa lineal que produce una distribución de probabilidad. Por lo general, se eligen los expertos con las puntuaciones top-K y la activación final se calcula como un promedio ponderado, sumando las salidas de los expertos multiplicadas por un peso derivado de la distribución de probabilidad del enrutador.
Para minimizar la latencia en sistemas MoE distribuidos, se puede aprovechar el paralelismo en múltiples dispositivos, pero esto introduce desafíos de comunicación. Modelos como Mixtral 8x7B o Llama-70B caben dentro de 8 dispositivos en un solo nodo, beneficiándose de interconexiones NVLink rápidas y de baja latencia (hasta 900Gbps). Sin embargo, los modelos más grandes requieren fragmentar expertos en múltiples nodos usando InfiniBand (que alcanza un pico de 400Gbps), lo que introduce desafíos de latencia adicionales.
En este artículo, exploramos el problema del paralelismo de expertos, describiendo nuestra implementación de núcleos de GPU que envían tokens de manera eficiente a los dispositivos que contienen los expertos asignados y los recopilan calculando la suma ponderada de las salidas de los expertos. Si bien existen implementaciones optimizadas agresivamente dirigidas a hardware de red específico, presentamos una implementación altamente portátil que se basa en un conjunto mínimo de primitivas NVSHMEM pero que ofrece un rendimiento 10 veces más rápido que la comunicación estándar de todos a todos. Nuestra implementación logra un rendimiento de vanguardia en configuraciones de un solo nodo mientras mantiene una excelente portabilidad en varios entornos de red.
Fragmentación y paralelismo
Para una inferencia eficiente, los pesos de un modelo deben mantenerse en la memoria del dispositivo, dejando al mismo tiempo suficiente espacio para activaciones, memorias caché KV y otros búferes requeridos por el pase hacia adelante a través del modelo. Los modelos más capaces superan la capacidad incluso de las GPU más capaces, por lo que la inferencia debe extenderse a través de múltiples dispositivos, que pueden almacenar colectivamente los pesos del modelo. Según los esquemas de fragmentación de pesos, se deben utilizar diferentes esquemas de comunicación y computación para descargar la computación y sincronizar los dispositivos.
El paralelismo de expertos (EP), ilustrado en la primera figura, solo paraleliza la computación de expertos. Se asignan diferentes expertos a diferentes dispositivos, que mantienen sus pesos. Después del enrutamiento, los tokens se envían al dispositivo correspondiente, y los resultados se recopilan y acumulan posteriormente. La complejidad del enrutamiento depende del grado de paralelismo en las otras partes del modelo: la replicación de otras capas podría eliminar la necesidad de enrutamiento por completo, ya que cada rango puede seleccionar los tokens de una tabla de enrutamiento replicada localmente. Sin embargo, si solo uno de los rangos ejecuta el enrutamiento, se requiere una transmisión para enviar tokens, índices y pesos a sus respectivos expertos. Finalmente, una recopilación total o una transmisión de todos a todos sincroniza los tokens de salida con cualquier rango que continúe la ejecución del modelo. Tal implementación es relativamente simple ya que torch ya expone las primitivas requeridas, aunque se podrían obtener algunos beneficios fusionando la acumulación con la operación de recopilación que reúne los tokens de los expertos.
El paralelismo de solo expertos no escala idealmente, ya que los nodos en un clúster podrían estar inactivos mientras el modelo ejecuta capas que no son de expertos, como la atención, la norma y el muestreo. Sin embargo, la computación de estas capas, principalmente la atención, también puede beneficiarse del paralelismo de tensores (TP). La mayoría de los modelos dependen de la atención de múltiples cabezales, lo que significa que los cabezales de atención y sus proyecciones Q, K y V correspondientes también pueden fragmentarse entre dispositivos, replicando o recopilando los segmentos entre varias capas. Si la atención se distribuye entre todos los dispositivos, una recopilación total puede sincronizar las activaciones, lo que permite que el enrutamiento sea replicado, requiriendo primitivas de sincronización similares al caso de paralelismo de expertos para una implementación eficiente. Sin embargo, existen límites al paralelismo en este nivel, ya que reducir el número de cabezales de atención por debajo de un cierto umbral producirá rendimientos decrecientes.
Para utilizar mejor todos los dispositivos y admitir un grado muy alto de paralelismo de expertos, de hasta 128 o 256 GPU, se requiere paralelismo de datos (DP). Bajo este esquema, los dispositivos en los que se divide un modelo se agrupan para manejar las solicitudes simultáneamente, calculando la atención y manteniendo las cachés KV fragmentadas en su grupo local. Múltiples instancias de estos grupos paralelos colaboran en la evaluación de expertos, cada una albergando un subconjunto diferente de los pesos de los expertos. Según el número de cabezales de atención, un grupo puede abarcar normalmente hasta el tamaño de un nodo completo, ya que la comunicación intra-nodo es más rápida. Por ejemplo, en la figura anterior, un rango DP sirve de forma independiente dos solicitudes, A y B, manejando la atención, la norma y cualquier otra contabilidad para las solicitudes. El otro rango DP procesa una solicitud distinta C. Sin embargo, el primer nodo alberga la mitad de los expertos, mientras que el otro nodo la otra mitad, por lo que después de enrutar los tokens de A y B podrían enviarse al segundo nodo y viceversa. Esto conduce a un problema de comunicación dispersa: cada dispositivo puede enviar un número diferente de tokens a cualquier otro rango de destino. Las primitivas existentes de torch, principalmente all_to_all, no son particularmente adecuadas, ya que pueden requerir alguna forma de relleno o sincronización de GPU a CPU y transmisión de metadatos. Para implementar la comunicación de manera efectiva, se requieren núcleos personalizados para procesar la información de enrutamiento e iniciar la comunicación desde los dispositivos sin intervención de la CPU. Después del enrutamiento, un núcleo de despacho debe enviar tokens a los rangos a los que fueron enrutados, mientras que en el lado de combinación se deben recopilar las activaciones que pertenecen a las solicitudes en el grupo DP actual. Además, el trabajo debe equilibrarse dentro de un grupo DP que puede tener múltiples dispositivos, para minimizar la transmisión y replicar correctamente los tokens en todos los rangos para las capas subsiguientes.
NVSHMEM
NVSHMEM es una implementación de OpenSHMEM específica de NVIDIA, que proporciona instalaciones de comunicación entre dispositivos portátiles que abstraen la complejidad del hardware subyacente. La API puede expresar lecturas y escrituras de dispositivo a dispositivo, que se asignan a las primitivas de las capas de transporte individuales. Se admiten tanto NVLink como RDMA, lo que otorga un grado de portabilidad y permite que los núcleos NVSHMEM operen dentro de un nodo o en un clúster de múltiples nodos. En nuestros núcleos, utilizamos escrituras en memoria remota y operaciones de señalización para transferir datos y sincronizar los dispositivos participantes.
Las operaciones de NVSHMEM se construyen en torno al concepto de memoria simétrica: operan en búferes que se han asignado en todos los dispositivos que participan en la comunicación entre dispositivos. Un dispositivo local puede usar una dirección derivada dentro de su propio búfer local junto con el índice del rango de destino para especificar el destino de una operación. La figura a continuación ilustra este concepto: ambas GPU asignan búferes simétricos del mismo tamaño, reteniendo punteros src a ellos. El primer rango quiere enviar 3 enteros al segundo, colocándolos al comienzo del búfer: nvshmem_int_put_nbi deriva la dirección de inicio del búfer local, especificando el dispositivo de destino. El segundo rango deriva un desplazamiento de su propio búfer, enviando un elemento al primer dispositivo, compensando por uno. Si bien las direcciones de destino siempre deben ser búferes simétricos asignados usando nvshmem_alloc, los búferes de origen pueden ser regiones arbitrarias de la memoria del dispositivo, siempre que estén pre-registradas con NVSHMEM.
Si bien NVSHMEM proporciona una amplia gama de primitivas, nuestros núcleos se basan en solo 3 funciones, construyendo toda la sincronización y el cercado sobre ellas.
nvshmemx_putmem_signal_nbi_warp: Transfiere un bloque de datos de un dispositivo a otro, mientras establece también una bandera en el dispositivo remoto. La operación establece (NVSHMEM_SIGNAL_SET) o incrementa (NVSHMEM_SIGNAL_ADD) una ubicación de 64 bits. La bandera se actualiza después de que se transfiere todo el bloque de memoria. Si el dispositivo remoto observa un cambio en la bandera, puede acceder de forma segura al búfer en su propia memoria. Esta función es útil para fusionar la transferencia de datos y la sincronización.
nvshmemx_signal_op opera en una sola ubicación de memoria, típicamente una bandera de 64 bits, estableciéndola o incrementándola atómicamente. Es útil para enviar metadatos y sincronizar dispositivos.
nvshmem_uint64_wait_until se utiliza en el extremo receptor de una señal, para sondear una bandera hasta que el remoto la actualice.
Garantizar cualquier forma de orden entre operaciones a través de nvshmem_quiet o nvshmem_fence es costoso, por lo que nuestra implementación de los núcleos evita el uso de cualquier otra primitiva de NVSHMEM y minimiza cualquier dependencia que no sean pares individuales de envío-recepción. Al enviar datos, siempre utilizamos la versión no bloqueante de las funciones, sin esperar a que los datos se envíen desde el rango local. Otra sincronización implícita en todo el grupo de núcleos asegura que estos búferes no se sobrescriban destructivamente mientras las NIC necesitan acceder a ellos.
NVSHMEM utiliza GPUDirect RDMA para que la NIC pueda leer y escribir directamente la memoria de la GPU para el intercambio de datos sin involucrar a las CPU. Además, en las NIC ConnectX, NVSHEMEM admite la comunicación iniciada por GPU (también conocida como Infiniband GPUDirect Async o IBGDA), que permite que la GPU publique operaciones RDMA directamente en la NIC y sondee la cola de finalización de la NIC directamente. En plataformas que no admiten la comunicación iniciada por la GPU, NVSHMEM genera un hilo "proxy" en la CPU host para iniciar la comunicación y sondear la finalización en nombre de la GPU. El programa NVSHMEM es portátil independientemente de si la comunicación iniciada por GPU es compatible o no. Sin embargo, la comunicación iniciada por GPU reduce significativamente la latencia porque evita por completo el desvío a la CPU.
Núcleos portátiles
Implementamos la comunicación MoE a través de un par de núcleos de despacho y combinación. Los núcleos de despacho son responsables de leer tokens e información de enrutamiento en cada rango, enviándolos a los expertos apropiados. Los núcleos de combinación recopilan las activaciones producidas por los expertos y las envían de vuelta a sus rangos de origen, mientras calculan el promedio ponderado de los expertos seleccionados en función de los pesos calculados por el enrutador. Los núcleos se dividen además en un componente de envío y recepción, con el fin de permitir que las transferencias de datos se solapen con la computación. Los núcleos de envío no bloquean y no sincronizan: simplemente envían todas las escrituras a los remotos. En el otro extremo, los núcleos de combinación solo leen de la memoria, esperando hasta que se hayan transferido todos los datos necesarios. Después de enviar el trabajo a las NIC, mientras los datos se transfieren de forma asíncrona a través del cable, las GPU pueden realizar otro trabajo útil localmente, como aplicar expertos compartidos o calcular la atención.
Cada par de núcleos tiene sus propios búferes de memoria simétricos, cada rango asigna almacenamiento privado para recibir datos de todos los demás rangos. El número máximo de tokens que se pueden enviar desde un grupo DP es fijo en todos los rangos, lo que también establece el límite superior que cada rango puede recibir para cada experto local de cada rango DP. Esto permite a los rangos emisores derivar una dirección única en el rango de destino para escribir, sin requerir ninguna sincronización entre ellos. Después de recibir los datos, los núcleos barajan los tokens para colocarlos en la memoria en el formato óptimo requerido por los núcleos receptores. Si bien los búferes tienen una dimensión considerable, se reutilizan en todas las capas secuenciales de un modelo.
La única forma de sincronización global, como se ilustra en la figura anterior, se implementa en el núcleo de combinación-recepción. Una vez que se envían los datos desde el envío, un rango regresa y continúa la ejecución cuando recibe todos los tokens que requiere de los otros rangos y entra en los núcleos de envío de combinación tan pronto como se procesan. La barrera en la combinación-recepción asegura que ningún rango pueda adelantarse y comenzar el despacho-envío mientras cualquier otro rango todavía está esperando recibir datos, lo que podría causar un solapamiento destructivo. La sincronización se realiza en el núcleo de combinación para simplificar, como una optimización, la misma barrera podría implementarse entre la recepción del despacho y los núcleos de envío de combinación, reduciendo aún más la latencia al permitir que las NIC tengan más tiempo para resolver las transferencias mientras la GPU ejecuta otros núcleos.
Ambos núcleos se dividen entre todos los SM disponibles de los dispositivos: mientras que los núcleos de despacho-envío y combinación-recepción deben paralelizarse a través de un conteo máximo de tokens por rango (max_m), los núcleos de despacho-recepción y combinación-envío deben manejar esa cantidad de tokens de cada rango y experto local, para un máximo de max_m * (num_experts // EP) * (EP // TP).
Despacho
El núcleo de despacho es responsable de enviar tokens y bloques de factores de escala a los pares que alojan a los expertos a los que se enrutaron los tokens. El lado del emisor se basa en la especialización de urdimbre para paralelizar dos tareas: agregar información de enrutamiento para determinar cuántos tokens se envían desde cada rango y empaquetar los tokens en mensajes para ser enviados al remoto. El lado del receptor primero espera a que se reciban todos los conteos de tokens, luego lee y desempaqueta las cargas útiles de la memoria compartida en los tensores que se pasarán a los núcleos Grouped GEMM descendentes. También almacena información en búferes compartidos con los núcleos de combinación, para indicar dónde debe enviarse cada token. Esta información es necesaria ya que el núcleo de recepción baraja los tokens en búferes contiguos en un orden no determinista.
En la parte del emisor, una sola urdimbre de 32 hilos en cada bloque es responsable de leer la información de enrutamiento y contar la cantidad de tokens que se espera que cada experto de destino reciba de este rango, enviando el recuento más uno usando nvshmem_signal_op. El recuento se incrementa en uno, ya que la transición de cero a no cero en el extremo remoto significa la recepción de los recuentos de un rango de origen. En paralelo, las urdimbres restantes cooperan para copiar tokens en la memoria simétrica a través de todos los bloques en paralelo, empaquetando activaciones, factores de escala y su índice en el rango local en un trozo contiguo. El índice es requerido por el emisor de combinación para determinar la dirección donde se escribirá el token. A continuación, después de asegurar que todos los datos se hayan copiado a través de una barrera en los grupos de urdimbre, las urdimbres vuelven a operar de forma independiente, cada una enviando el mismo búfer a un experto diferente en paralelo. Los tokens se envían usando nvshmemx_putmem_signal_nbi_warp, que también aumenta atómicamente el conteo de tokens enviados desde el rango local en el dispositivo remoto. Dentro de un grupo DP, dado que cada rango posee una réplica del token que se enviará, el despacho se equilibra uniformemente, y cada dispositivo envía un subconjunto de los tokens.
En el extremo de recepción, todos los núcleos se sincronizan primero con los rangos emisores esperando que se envíen los conteos totales de tokens. Después, todos esperan a que los conteos de tokens enviados, incrementados atómicamente, se establezcan en los conteos totales, lo que indica que todas las cargas útiles de los rangos de origen también se han enviado, gracias a la semántica de la llamada putmem. Los núcleos sondean los conteos usando nvshmem_uint64_wait_until, paralelizando la operación a través de todos los bloques e hilos. Posteriormente, una barrera entre bloques asegura que ningún bloque lea los búferes a menos que todos los datos se hayan recibido correctamente. Esparcidos entre bloques y sincronizados a través de un contador incrementado atómicamente, los tokens se copian de la memoria simétrica a búferes contiguos regulares que se convierten en las entradas de los núcleos descendentes que implementan los expertos. El rango de origen, el índice de experto y el índice de token se almacenan por separado, señalando exactamente la ubicación donde el núcleo de combinación tiene que enviar las activaciones. Aunque los tokens de un grupo DP se envían desde diferentes dispositivos, todos se agrupan para ser pasados al experto correspondiente.
Combinar
Los núcleos de combinación se dividen de nuevo en mitades de envío y receptor: los emisores copian las activaciones de 16 bits no cuantificadas a los dispositivos remotos, con los núcleos de recepción esperando a que los datos se envíen y calculando el promedio ponderado de todas las contribuciones de expertos localmente. Además, también actúan como una barrera, para sincronizar la secuencia despacho-combinación: cada rango establece una bandera en cada par al entrar en los núcleos de envío, y los núcleos de recepción no pueden regresar a menos que observen que la bandera está establecida. La latencia de sincronización es mínima, ya que se solapa con la comunicación y la computación reales.
En el lado del emisor, los núcleos atraviesan la lista de tokens asignados a todos los expertos locales en paralelo, escribiéndolos en un búfer en el rango de destino. El rango de destino, el índice de experto y el índice de token se leen de los búferes por token poblados por los núcleos de dispersión tras la recepción de los tokens. Cada emisor tiene su propia región de memoria privada por experto para escribir, como se indica en la figura anterior, evitando la necesidad de sincronizar. De manera similar al despacho, la combinación incrementa atómicamente los contadores por token en el rango de destino para indicar la recepción de los datos: cuando el contador coincide con el número de expertos a los que se envió un token, se puede acceder al contenido del token.
En el núcleo de recepción, la lista de tokens se atraviesa en paralelo a través de múltiples bloques, esperando a que lleguen sus contenidos sondeando la bandera establecida por la operación de señalización. Al llegar, las cargas útiles se leen de los búferes privados, con la tabla de enrutamiento indicando de qué búfer leer y qué peso asignar a cada experto. Los resultados se escriben luego en tensores asignados externamente, terminando el núcleo la ejecución una vez que todos los dispositivos pasaron la barrera. En un grupo DP, todos los rangos reciben una copia de cada activación de experto para calcular sus propias réplicas.
Evaluaciones comparativas
Evaluamos nuestros núcleos en un clúster de 128 GPU distribuidas en 16 nodos conectados a través de InfiniBand y NIC CX-7. Probamos tanto GPUDirect Async (IBGDA) como Reliable Connection (RC) con un proxy de CPU. Los comparamos con la implementación altamente optimizada de DeepSeek, así como con las primitivas densas proporcionadas por PyTorch (a través de NCCL) o NVSHMEM.
Aunque en la operación denso NVSHMEM de todos a todos, el rendimiento de IBRC e IBGDA es similar (6378 µs vs 6180 µs), IBGDA es significativamente más rápido con los núcleos dispersos. Sumando el despacho y la combinación, IBGDA usa 902 µs mientras que IBRC toma 3223 µs: una mejora de 3,6 veces en la latencia. Mientras que el de todos a todos está limitado por el ancho de banda, los núcleos dispersos transmiten órdenes de magnitud menos datos, estando limitados por la latencia. Al activar las transferencias de red directamente desde una GPU, sin requerir un proxy de CPU para coordinar la GPU y la NIC, la latencia de extremo a extremo se reduce significativamente.
Si bien nuestros núcleos portátiles son aproximadamente 2 veces más lentos que los núcleos DeepSeek altamente optimizados, mejoran la latencia en 10 veces en comparación con los núcleos densos (902 µs vs 9944 µs).
Además, la división en componentes emisor-receptor también permite ocultar parte de la latencia, a diferencia de las primitivas de la biblioteca.
En un solo nodo (EP8), NVSHMEM utiliza NVLINK para el transporte, lo que ofrece una menor latencia y un mayor rendimiento que las redes entre nodos. Nuestros núcleos portátiles son aproximadamente 2,5 veces más rápidos que DeepEP en un solo nodo (186µs vs 481 µs).
Más mejoras
Los núcleos descritos aquí superan a las primitivas integradas de los marcos de ML y ofrecen un rendimiento decente sin sobre-especializarse para transportes particulares entre dispositivos, como NVLink o InfiniBand. Además de las oportunidades ya mencionadas, se pueden obtener más ganancias de rendimiento reemplazando las primitivas de comunicación con versiones más especializadas. Por ejemplo, a través de NVLink, el uso de memoria simétrica podría reemplazarse con búferes compartidos entre los dispositivos, eliminando algunas copias y permitiendo esquemas de sincronización más finos, a través de tokens individuales en lugar de lotes de tokens. A través de InfiniBand, una implementación podría acceder directamente a los pares de colas subyacentes, eliminando la necesidad de transferir tanto los recuentos de tokens esperados como enviados y vaciando los tokens de las colas en los búferes de salida a medida que llegan. Sin embargo, tales implementaciones tienen el costo de la portabilidad, mientras que nuestras implementaciones permiten que se evalúen clústeres con configuraciones específicas antes de comprometer el esfuerzo de desarrollo para optimizar el hardware en particular.
Conclusión
Hemos presentado una biblioteca de alto rendimiento y portátil para la comunicación MoE que logra un rendimiento 10 veces más rápido en comparación con la comunicación estándar de todos a todos mientras mantiene la compatibilidad entre diversas configuraciones de hardware. En implementaciones de un solo nodo con NVLink, nuestra solución demuestra una latencia 2,5 veces menor que las implementaciones anteriores.
Nuestro enfoque equilibra el rendimiento con la portabilidad a través de innovaciones clave, incluido el soporte de comunicación iniciada por GPU, una arquitectura de núcleo dividido que permite el solapamiento computación-comunicación y un despacho de tokens eficiente mediante el uso de primitivas NVSHMEM mínimas. Si bien es aproximadamente 2 veces más lento que las implementaciones altamente especializadas en configuraciones de múltiples nodos, nuestra biblioteca ofrece una flexibilidad superior en varios entornos de red (NVLink, CX-7 y EFA).
A medida que los modelos MoE continúan escalando, las estrategias de comunicación eficientes como la nuestra serán cada vez más importantes para la implementación práctica. Nuestra implementación completamente de código abierto está disponible en https://github.com/ppl-ai/pplx-kernels.
Referencias
Informe técnico de DeepSeek-V3
Cita
@online{perplexity2025EfficientAndPortableMixtureOfExpertsCommunication,
author = {{Perplexity} and Nandor Licker and Lequn Chen and Phi Hoang},
title = {{Efficient and portable mixture-of-experts communication}},
date = {2025-04-02},
url = {https://perplexity.coolkeypoint.com/hub/blog/efficient-and-portable-mixture-of-experts-communication}
}