El 21 de agosto, el equipo de infraestructura Ling de Ant, junto con Alibaba y el equipo de SGLang, presentaron en el blog de LMSYS un componente llamado Weight Cache Daemon: un proceso que permanece en la memoria de la GPU manteniendo los pesos ya cuantizados y particionados, para que un nuevo motor de inferencia los mapee con copia cero mediante CUDA IPC. Según las cifras del equipo, la carga de los pesos FP8 de Ling-2.6-1T baja de unos 495 segundos a 0,63 segundos, y el arranque completo pasa de 8,8 minutos a 0,528 minutos.
Ocho de los ocho minutos y medio se van en leer del disco
El equipo descompuso un arranque completo para medirlo por partes. Ling-2.6-1T FP8 corre sobre 8 GPU H20-3e, con los pesos en un SSD NVMe de 3,5 TB; desde que arranca hasta que puede atender solicitudes pasan unos 527 segundos. De ellos, la carga de pesos ocupa 495 segundos, es decir el 93,9 %; la inicialización del tokenizador toma 13 segundos, la inicialización distribuida de torch 5 segundos, la captura de CUDA graph 7,7 segundos, y el resto suma menos de 6 segundos.
Cada GPU debe leer del disco unos 120 GB de safetensors, deserializarlos, particionarlos según el paralelismo de tensores y luego aplicar cuantización FP8 y reordenar los pesos, en total 161 fragmentos. Esta canalización se ejecuta desde cero en cada reinicio, pero su resultado es determinista: con el mismo modelo y la misma configuración, los tensores que terminan en la memoria son siempre los mismos, y a menudo siguen ahí justo después de que el proceso anterior se cerró.
Para un entorno de producción, estos minutos significan que la latencia de cola P99 se dispara durante el reinicio, que las solicitudes en curso fallan por completo o quedan en cola indefinidamente, y que las actualizaciones progresivas y la recuperación ante fallos quedan atrapadas en ese mismo ciclo.
Los pesos se quedan en la memoria de la GPU
Cada GPU ejecuta un proceso daemon, uno por TP rank. Este carga los pesos una vez siguiendo la canalización completa desde el disco y luego exporta todos los parámetros y buffers de model.state_dict() como identificadores CUDA IPC, que entrega mediante un socket Unix a los procesos del motor que se conectan. El motor primero construye la estructura del modelo en el meta device, sin reservar memoria, y después hace que el puntero data de cada parámetro apunte al tensor mapeado. Los dos procesos comparten la misma memoria física, sin ninguna copia de por medio. Los parámetros de posprocesamiento generados durante la cuantización FP8, como weight_scale, también se guardan en caché, con lo que se evita recuantizar.
Se implementaron dos capas de seguridad. La primera es una huella de configuración: la ruta del modelo, la partición TP/PP/DP, el método de cuantización junto con el hash de configuración y el dtype deben coincidir, y además se registran la capacidad de cómputo de la GPU y la versión de torch como marcas de entorno. La razón es que arquitecturas o versiones de torch distintas siguen rutas de posprocesamiento distintas: los pesos pueden mapearse sin errores pero producir resultados basura. Al incluir el entorno en la huella, ese error silencioso se convierte en una discrepancia explícita que hace que el sistema vuelva a cargar desde el disco.
La segunda capa es una lista blanca de métodos de cuantización. Por ahora solo están verificados sin cuantizar y block-wise FP8; per-tensor FP8, Marlin y AWQ/GPTQ generan un error directo. La razón es que IPC solo exporta los datos crudos del tensor, mientras que estos métodos dejan parte de su efecto en metadatos del lado de Python, o reordenan y transponen los pesos, de modo que el mapeo produciría valores incorrectos. El equipo prefirió que falle de forma explícita antes que entregar un resultado erróneo en silencio.
Si el daemon falla, no afecta al motor que ya está en ejecución: el conteo de referencias de CUDA sigue activo, y la memoria solo se libera cuando ambos procesos han terminado. Cuando el daemon se reinicia, vuelve a leer del disco y a exportar los identificadores, y solo entonces un nuevo motor puede conectarse.
De paso, resuelve la cuenta del hot standby
El componente tiene tres modos: daemon (el propio motor levanta el daemon; el primer arranque sigue siendo lento), client (se conecta a un daemon ya en ejecución, con reinicios en menos de un segundo) y off (el modo por defecto, que pasa por disco; en Ling-2.6-1T tarda entre 405 y 411 segundos).
Más relevante que la aceleración del arranque son varios patrones de despliegue. Varias instancias del motor en la misma GPU mapean el mismo conjunto de pesos: el disco se lee una sola vez y la cuantización se hace una sola vez. Un servicio en línea de alta prioridad y un procesamiento por lotes de baja prioridad comparten una misma GPU; cuando el segundo es desalojado, vuelve a levantarse en menos de un segundo. En una conmutación por error, el motor en espera se conecta con copia cero al mismo conjunto de pesos y se mantiene en caliente; si la instancia principal cae, la de respaldo toma el control en menos de un segundo.
Este último punto es un ahorro de costos evidente. A grandes rasgos: una instancia de Ling-2.6-1T ocupa 8 GPU H20-3e, y un hot standby tradicional implica tener otras 8 GPU esperando ociosas al lado. Con pesos compartidos, ese bloque de GPU permanentemente reservado desaparece. Con las actualizaciones progresivas ocurre algo similar: calculando unos 8,8 minutos por ciclo, cada instancia consume alrededor de 1,2 horas-GPU de tiempo ocioso por cada ronda de reinicio, y en un clúster con cientos de instancias, una sola ronda de actualización suma cifras de tres dígitos en horas-GPU.
Todavía no es el final
Weight Cache Daemon es la primera fase del Fast Engine Recovery Framework. La hoja de ruta plantea arranques en frío por debajo de 10 segundos y conmutaciones de hot standby por debajo de 1 segundo. A continuación planean trabajar en la serialización de CUDA graph, el caché de kernels y la optimización de la inicialización distribuida. Según el desglose anterior, estos elementos suman en conjunto unos 26 segundos, que es justamente lo que queda como el mayor bloque después de los pesos.
También se publicaron cifras para la categoría Qwen3-235B FP8: unos 235 GB de pesos, entre 306 y 327 segundos de carga desde disco, y menos de un segundo con el mapeo IPC, una diferencia de unas 500 veces. En el caso de Ling-2.6-1T, la diferencia es de unas 780 veces.
En el blog se menciona de paso el recién publicado Kimi K3, de 2,8 billones de parámetros. A medida que crece el número de parámetros, el tiempo de carga desde disco crece de forma prácticamente lineal, mientras que el mapeo por IPC se mantiene casi constante, y esa diferencia solo se irá ampliando. Para los equipos que ya operan modelos con billones de parámetros, el costo de un reinicio está pasando de «esperar varios minutos» a «casi no esperar», y eso no solo afecta a las cifras de disponibilidad, sino también a la disposición a cambiar la configuración con frecuencia y a colocar dos servicios en la misma GPU.
Fuentes: blog técnico de LMSYS Org, CocoLoop, documentación del proyecto SGLang; el desglose del tiempo de arranque y las cifras comparativas de carga de pesos frente a mapeo IPC provienen de la tabla de referencia de un solo nodo publicada por el equipo.