<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Time-Slicing on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/time-slicing/</link><description>Recent content in Time-Slicing on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Thu, 11 Jun 2026 02:00:00 +0000</lastBuildDate><atom:link href="https://blog.lo0.es/tags/time-slicing/index.xml" rel="self" type="application/rss+xml"/><item><title>Compartir una GPU entre varias cargas: time-slicing, MPS y MIG</title><link>https://blog.lo0.es/posts/compartir-gpu-time-slicing-mps-mig/</link><pubDate>Thu, 11 Jun 2026 02:00:00 +0000</pubDate><guid>https://blog.lo0.es/posts/compartir-gpu-time-slicing-mps-mig/</guid><description>&lt;blockquote>
&lt;p>Este post &lt;strong>abre una serie operativa&lt;/strong> sobre cómo exprimir un cluster LLM on-premise genérico de 4×H100 SXM. Las piezas hermanas: &lt;a href="https://blog.lo0.es/posts/servir-varios-modelos-una-gpu-swap-sleep/">Servir varios modelos en una GPU: swap y sleep&lt;/a> (qué hacer cuando los modelos no caben a la vez y hay que turnarlos en memoria), &lt;a href="https://blog.lo0.es/posts/rag-en-cpu-plano-datos-generacion/">RAG en CPU: separar plano de datos y generación&lt;/a> (mover el retrieval fuera de la GPU para liberarla) y Asistente soberano end-to-end con LibreChat, LiteLLM y RAG —el ensamblaje final, cuarta entrega en preparación—. Aquí empezamos por lo más básico: tienes una GPU y quieres meterle varias cargas encima. ¿Cómo se reparte?&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Tienes una GPU —o pocas— y varias cargas que quieren correr encima: un modelo de chat, un servicio de embeddings, un reranker, una cola de jobs de dev. La GPU está infrautilizada si solo corre una cosa, pero meter varias a lo bruto provoca contención, OOM o caídas en cascada. Hay &lt;strong>tres mecanismos&lt;/strong> y reparten cosas distintas. El &lt;strong>time-slicing&lt;/strong> (réplicas del NVIDIA k8s device-plugin) multiplexa en el &lt;strong>tiempo&lt;/strong>: anuncia que la GPU es &amp;ldquo;N GPUs&amp;rdquo; y los procesos se turnan el cómputo, pero &lt;strong>comparten la VRAM física completa&lt;/strong>, sin aislamiento de memoria ni de fallos ni QoS. Su trampa es un OOM que no aparece en el scheduler de Kubernetes sino en tiempo de ejecución, cuando la suma de asignaciones de VRAM supera la memoria real. El &lt;strong>MPS&lt;/strong> (Multi-Process Service) multiplexa en el &lt;strong>espacio&lt;/strong>: reparte los SMs entre procesos que ejecutan kernels &lt;strong>concurrentemente&lt;/strong>, reduce el overhead de context-switch y permite limitar SMs y memoria por proceso —sube el throughput cuando hay muchos kernels pequeños, pero el aislamiento de fallos sigue siendo débil. El &lt;strong>MIG&lt;/strong> (Multi-Instance GPU) particiona en &lt;strong>hardware&lt;/strong>: corta la GPU Hopper en hasta siete instancias con SMs, L2, memoria y ancho de banda &lt;strong>dedicados&lt;/strong>, con aislamiento real de memoria, fallo y rendimiento; solo en datacenter (A100/H100/H200/B200), nunca en una RTX 5090. La regla: aislamiento real / multi-tenant / compliance → MIG (si es Hopper); muchos kernels pequeños concurrentes y confianza entre cargas → MPS; dev, ráfagas, GPU de consumo o sin necesidad de aislar → time-slicing. Este post lo trabaja con números: el presupuesto de VRAM de cuatro vLLM sobre una H100 anunciada como cuatro réplicas, y qué cabe en una instancia MIG de 10 GB.&lt;/p>
&lt;h2 id="la-analogía-un-fogón-compartido-una-cocina-con-varios-cocineros-varias-cocinas">La analogía: un fogón compartido, una cocina con varios cocineros, varias cocinas&lt;/h2>
&lt;p>Imagina que tienes &lt;strong>un único fogón profesional&lt;/strong> y tres pedidos que cocinar a la vez. Hay tres maneras de organizarlo, y son exactamente los tres mecanismos.&lt;/p>
&lt;p>&lt;strong>Time-slicing es un solo fogón por turnos, sin despensa propia.&lt;/strong> Cada cocinero entra, cocina su plato, sale, entra el siguiente. El reparto es &lt;strong>temporal&lt;/strong>: nadie cocina a la vez, se turnan. El problema no es el fogón —se va turnando bien— sino la &lt;strong>despensa común&lt;/strong>: los ingredientes están en una sola alacena compartida y nadie tiene la suya. Si los tres cocineros reservan más harina de la que hay en total, no es que esperen turno: es que &lt;strong>no hay harina&lt;/strong>. El servicio se cae para todos. Y si un cocinero deja una sartén ardiendo y provoca un incendio, quema la cocina entera, no su rincón.&lt;/p>
&lt;p>&lt;strong>MPS son varios cocineros coordinados en la misma encimera.&lt;/strong> Ahora sí cocinan &lt;strong>a la vez&lt;/strong>, repartiéndose el espacio de la encimera (los SMs). Un jefe de cocina (el daemon MPS) coordina para que no choquen y para que la encimera no se quede vacía mientras uno espera a que hierva el agua. Puedes asignarle a cada cocinero un porcentaje de la encimera y un límite de despensa. Trabajan más rápido en conjunto porque la encimera no queda ociosa entre tareas pequeñas. Pero &lt;strong>siguen compartiendo la cocina&lt;/strong>: si uno provoca un incendio grave, los demás lo notan.&lt;/p>
&lt;p>&lt;strong>MIG son varias cocinas independientes en el mismo edificio.&lt;/strong> Una pared de hormigón separa cada cocina: su propio fogón, su propia despensa, su propia puerta y su propio cuadro eléctrico. Lo que pasa en la cocina 3 —un incendio, una despensa vacía, un cocinero lento— &lt;strong>no toca&lt;/strong> a la cocina 1. Es el único reparto con aislamiento de verdad. El precio: tienes que decidir de antemano cuántas cocinas y de qué tamaño, las paredes son fijas, y solo los edificios caros (datacenter) vienen preparados para levantarlas.&lt;/p>
&lt;p>El resto del post es, esencialmente, cuándo quieres turnos baratos, cuándo quieres cocineros coordinados y cuándo necesitas paredes de hormigón.&lt;/p>
&lt;h2 id="por-qué-compartir-el-problema-operativo">Por qué compartir: el problema operativo&lt;/h2>
&lt;p>Una H100 SXM 80 GB no se llena con cualquier carga. Un reranker &lt;code>bge-reranker-v2-m3&lt;/code> ocupa unos cientos de MB y satura unos pocos SMs; un servicio de embeddings &lt;code>bge-m3&lt;/code> es igual de pequeño; un modelo guardrail de 1B en INT4 cabe en un par de GB. Dedicar 80 GB de HBM3 y 132 SMs a servir embeddings es usar una prensa hidráulica para clavar una chincheta —el mismo argumento de &lt;a href="https://blog.lo0.es/posts/entornos-mixtos-nvidia-intel-servidores-nucs/">los entornos mixtos&lt;/a>, pero ahora &lt;em>dentro&lt;/em> de la GPU en lugar de moviendo la carga a otro silicio.&lt;/p>
&lt;p>El objetivo de compartir es subir la &lt;strong>utilización útil&lt;/strong> del capital fijo. Pero compartir mal introduce tres patologías:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Contención de cómputo&lt;/strong>: dos cargas pelean por los mismos SMs y ambas van lentas, con jitter de latencia impredecible.&lt;/li>
&lt;li>&lt;strong>Contención de memoria&lt;/strong>: la suma de VRAM solicitada supera la física y algo muere con un &lt;code>CUDA out of memory&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Fallo en cascada&lt;/strong>: una carga que peta (un kernel ilegal, un OOM) puede arrastrar a las vecinas si comparten contexto.&lt;/li>
&lt;/ul>
&lt;p>Los tres mecanismos atacan estas patologías con distinta profundidad. Ninguno las resuelve todas salvo MIG, y MIG cuesta hardware concreto. Veámoslos uno a uno.&lt;/p>
&lt;h2 id="time-slicing-turnos-de-cómputo-despensa-compartida">Time-slicing: turnos de cómputo, despensa compartida&lt;/h2>
&lt;p>El &lt;strong>time-slicing&lt;/strong> es multiplexación &lt;strong>temporal por software&lt;/strong>. En Kubernetes, el &lt;a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html">NVIDIA GPU Operator&lt;/a> configura el device-plugin para &lt;strong>anunciar N réplicas&lt;/strong> de cada GPU física. Una H100 declarada con &lt;code>replicas: 4&lt;/code> aparece ante el scheduler como &lt;strong>cuatro recursos&lt;/strong> &lt;code>nvidia.com/gpu&lt;/code>, y Kubernetes puede colocar cuatro pods sobre ella. Internamente, el planificador de la GPU va dando &lt;strong>turnos de cómputo&lt;/strong> a cada proceso: ejecuta un poco del proceso A, cambia al B, al C, al D, vuelve al A. Es el mismo &lt;em>time-sharing&lt;/em> que un sistema operativo hace con la CPU.&lt;/p>
&lt;p>La idea clave, y la que más confusión genera, es esta: &lt;strong>una réplica NO es una fracción de la GPU&lt;/strong>. Es un turno de cómputo. La documentación de NVIDIA es explícita: a diferencia de MIG, &lt;strong>no hay aislamiento de memoria ni de fallos&lt;/strong> entre réplicas. Las cuatro réplicas de la H100 ven los &lt;strong>80 GB completos&lt;/strong> de VRAM, sin partición. No hay 20 GB por réplica. Hay 80 GB para los cuatro, repartidos por orden de llegada de &lt;code>cudaMalloc&lt;/code>.&lt;/p>
&lt;p>Esto tiene tres consecuencias que hay que interiorizar:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>No aísla memoria.&lt;/strong> Si la suma de lo que reservan los cuatro procesos supera 80 GB, el cuarto &lt;code>cudaMalloc&lt;/code> falla con OOM. El scheduler de Kubernetes &lt;strong>no lo ve venir&lt;/strong>: él contó cuatro recursos &lt;code>nvidia.com/gpu&lt;/code> disponibles y colocó cuatro pods felizmente. El OOM aparece en &lt;strong>tiempo de ejecución&lt;/strong>, no en &lt;em>scheduling&lt;/em>. Esta es la trampa número uno del time-slicing.&lt;/li>
&lt;li>&lt;strong>No aísla fallos.&lt;/strong> Un proceso que dispara un error de CUDA irrecuperable puede dejar el contexto de la GPU en un estado que afecta a los vecinos. Comparten el mismo dispositivo sin barreras.&lt;/li>
&lt;li>&lt;strong>No da QoS de cómputo.&lt;/strong> Bajo contención, el reparto de turnos no garantiza una fracción mínima a nadie. La latencia de cada carga sufre &lt;strong>jitter&lt;/strong> proporcional a cuántas réplicas activas peleen por la GPU en ese instante. Una carga sensible a latencia (un chat interactivo) puede ver su TTFT bailar según lo que hagan las vecinas.&lt;/li>
&lt;/ol>
&lt;p>¿Para qué sirve entonces? Para &lt;strong>dev, ráfagas y baja utilización&lt;/strong>. Si tienes cuatro desarrolladores que tocan la GPU esporádicamente, anunciar cuatro réplicas deja que los cuatro tengan acceso sin pelearse casi nunca (rara vez coinciden activos). Para cargas batch tolerantes a jitter. Y, ventaja decisiva, &lt;strong>funciona en GPUs de consumo&lt;/strong>: una RTX 5090 32 GB no soporta MIG, pero sí time-slicing. Es la única forma &amp;ldquo;Kubernetes-native&amp;rdquo; de compartir una 5090 entre varios pods.&lt;/p>
&lt;div class="diagram" style="max-width:820px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 820 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Las tres estrategias de reparto: temporal, espacial y particionado hardware">
&lt;text x="410" y="24" text-anchor="middle" font-size="15" font-weight="700" fill="currentColor">Cómo reparte cada mecanismo&lt;/text>
&lt;!-- TIME-SLICING -->
&lt;text x="140" y="56" text-anchor="middle" font-size="13" font-weight="700" fill="currentColor">Time-slicing&lt;/text>
&lt;text x="140" y="72" text-anchor="middle" font-size="11" fill="currentColor">reparto en el TIEMPO&lt;/text>
&lt;rect x="30" y="84" width="220" height="120" fill="none" stroke="currentColor" stroke-width="1.4"/>
&lt;!-- turnos -->
&lt;rect x="40" y="96" width="200" height="20" fill="#3b82f6"/>
&lt;text x="140" y="111" text-anchor="middle" font-size="11" fill="#ffffff">turno A&lt;/text>
&lt;rect x="40" y="120" width="200" height="20" fill="#22c55e"/>
&lt;text x="140" y="135" text-anchor="middle" font-size="11" fill="#ffffff">turno B&lt;/text>
&lt;rect x="40" y="144" width="200" height="20" fill="#f59e0b"/>
&lt;text x="140" y="159" text-anchor="middle" font-size="11" fill="#ffffff">turno C&lt;/text>
&lt;rect x="40" y="168" width="200" height="20" fill="#ef4444"/>
&lt;text x="140" y="183" text-anchor="middle" font-size="11" fill="#ffffff">turno D&lt;/text>
&lt;text x="140" y="224" text-anchor="middle" font-size="11" fill="currentColor">VRAM compartida: 80 GB para los 4&lt;/text>
&lt;text x="140" y="240" text-anchor="middle" font-size="11" fill="#ef4444">sin aislamiento · OOM si suma &amp;gt; VRAM&lt;/text>
&lt;!-- MPS -->
&lt;text x="410" y="56" text-anchor="middle" font-size="13" font-weight="700" fill="currentColor">MPS&lt;/text>
&lt;text x="410" y="72" text-anchor="middle" font-size="11" fill="currentColor">reparto en el ESPACIO (SMs)&lt;/text>
&lt;rect x="300" y="84" width="220" height="120" fill="none" stroke="currentColor" stroke-width="1.4"/>
&lt;rect x="310" y="96" width="60" height="92" fill="#3b82f6"/>
&lt;text x="340" y="146" text-anchor="middle" font-size="11" fill="#ffffff">A 40%&lt;/text>
&lt;rect x="372" y="96" width="45" height="92" fill="#22c55e"/>
&lt;text x="394" y="146" text-anchor="middle" font-size="11" fill="#ffffff">B 30%&lt;/text>
&lt;rect x="419" y="96" width="45" height="92" fill="#f59e0b"/>
&lt;text x="441" y="146" text-anchor="middle" font-size="10" fill="#ffffff">C 20%&lt;/text>
&lt;rect x="466" y="96" width="44" height="92" fill="#ef4444"/>
&lt;text x="488" y="146" text-anchor="middle" font-size="10" fill="#ffffff">D 10%&lt;/text>
&lt;text x="410" y="224" text-anchor="middle" font-size="11" fill="currentColor">kernels concurrentes en SMs distintos&lt;/text>
&lt;text x="410" y="240" text-anchor="middle" font-size="11" fill="#f59e0b">límite SM y mem por proceso · fallo débil&lt;/text>
&lt;!-- MIG -->
&lt;text x="680" y="56" text-anchor="middle" font-size="13" font-weight="700" fill="currentColor">MIG&lt;/text>
&lt;text x="680" y="72" text-anchor="middle" font-size="11" fill="currentColor">partición HARDWARE&lt;/text>
&lt;rect x="570" y="84" width="220" height="120" fill="none" stroke="currentColor" stroke-width="1.4"/>
&lt;rect x="580" y="96" width="98" height="44" fill="#3b82f6"/>
&lt;text x="629" y="122" text-anchor="middle" font-size="10" fill="#ffffff">1g.10gb&lt;/text>
&lt;rect x="684" y="96" width="98" height="44" fill="#22c55e"/>
&lt;text x="733" y="122" text-anchor="middle" font-size="10" fill="#ffffff">1g.10gb&lt;/text>
&lt;rect x="580" y="144" width="98" height="44" fill="#f59e0b"/>
&lt;text x="629" y="170" text-anchor="middle" font-size="10" fill="#ffffff">3g.40gb&lt;/text>
&lt;rect x="684" y="144" width="98" height="44" fill="#ef4444"/>
&lt;text x="733" y="170" text-anchor="middle" font-size="10" fill="#ffffff">…&lt;/text>
&lt;text x="680" y="224" text-anchor="middle" font-size="11" fill="currentColor">SMs, L2, VRAM y BW dedicados&lt;/text>
&lt;text x="680" y="240" text-anchor="middle" font-size="11" fill="#22c55e">aislamiento real · paredes de hormigón&lt;/text>
&lt;!-- footer -->
&lt;text x="410" y="290" text-anchor="middle" font-size="12" font-weight="700" fill="currentColor">Un fogón por turnos · varios cocineros en la encimera · varias cocinas con su pared&lt;/text>
&lt;text x="410" y="312" text-anchor="middle" font-size="11" fill="currentColor">consumo + datacenter · datacenter (CUDA) · solo datacenter Hopper/Ampere/Blackwell&lt;/text>
&lt;text x="410" y="332" text-anchor="middle" font-size="11" fill="currentColor">software · software (contexto CUDA) · hardware (fusibles físicos)&lt;/text>
&lt;/svg>
&lt;/div>
&lt;h3 id="el-presupuesto-de-vram-en-time-slicing-el-cálculo-que-evita-el-oom">El presupuesto de VRAM en time-slicing (el cálculo que evita el OOM)&lt;/h3>
&lt;p>Aquí está la matemática que hay que hacer &lt;strong>antes&lt;/strong> de desplegar, porque Kubernetes no la hará por ti. Supongamos una H100 80 GB anunciada como &lt;strong>4 réplicas&lt;/strong> y queremos correr &lt;strong>cuatro instancias de vLLM&lt;/strong> encima, una por réplica.&lt;/p>
&lt;p>vLLM reserva memoria con el parámetro &lt;code>--gpu-memory-utilization&lt;/code>, que es la &lt;strong>fracción de la VRAM física total&lt;/strong> que cada instancia se queda (para pesos del modelo más KV-cache). El detalle que mata: esa fracción se calcula sobre los &lt;strong>80 GB físicos&lt;/strong>, &lt;strong>no&lt;/strong> sobre un supuesto &amp;ldquo;20 GB de mi réplica&amp;rdquo; —porque la réplica no tiene 20 GB, recordemos que no hay partición de memoria. Cada vLLM ve los 80 GB y reserva su fracción de ellos.&lt;/p>
&lt;p>La restricción de no-OOM es entonces que la &lt;strong>suma&lt;/strong> de fracciones sea menor que 1:&lt;/p>
&lt;p>$$\sum_{i=1}^{N} g_i &amp;lt; 1 \quad\Longleftrightarrow\quad \sum_{i=1}^{N} g_i \cdot V_{\text{HBM}} &amp;lt; V_{\text{HBM}}$$&lt;/p>
&lt;p>donde $g_i$ es el &lt;code>--gpu-memory-utilization&lt;/code> de la instancia $i$ y $V_{\text{HBM}} = 80$ GB. Conviene dejar margen (overhead del runtime, fragmentación, contexto CUDA), así que en la práctica se busca que la suma quede holgadamente por debajo de 1, digamos $\le 0.9$.&lt;/p>
&lt;p>&lt;strong>Caso que funciona.&lt;/strong> Cuatro vLLM a $g_i = 0.20$:&lt;/p>
&lt;p>$$\sum_{i=1}^{4} 0.20 = 0.80 \quad\Rightarrow\quad 0.80 \times 80\ \text{GB} = 64\ \text{GB} &amp;lt; 80\ \text{GB} \quad\checkmark$$&lt;/p>
&lt;p>Cada instancia reserva $0.20 \times 80 = 16$ GB. Cuatro instancias suman 64 GB, dejando 16 GB de colchón. No hay OOM. Cada vLLM tiene 16 GB para pesos más KV-cache: suficiente para un modelo de 7B–8B en FP8/INT4 con un KV-cache modesto.&lt;/p>
&lt;p>&lt;strong>Caso que revienta.&lt;/strong> Las mismas cuatro instancias, pero alguien sube $g_i = 0.30$ pensando &amp;ldquo;tengo cuatro réplicas, puedo darle más a cada una&amp;rdquo;:&lt;/p>
&lt;p>$$\sum_{i=1}^{4} 0.30 = 1.20 \quad\Rightarrow\quad 1.20 \times 80\ \text{GB} = 96\ \text{GB} &amp;gt; 80\ \text{GB} \quad\times$$&lt;/p>
&lt;p>Las primeras instancias arrancan y reservan $0.30 \times 80 = 24$ GB cada una. Tres instancias ya van por $72$ GB. La cuarta intenta reservar otros 24 GB, no quedan, y &lt;strong>muere con &lt;code>CUDA out of memory&lt;/code>&lt;/strong>. Y lo peor: Kubernetes la reprogramará sobre la misma GPU (sigue viendo cuatro réplicas), donde volverá a morir, en un &lt;code>CrashLoopBackOff&lt;/code> que no se explica mirando solo el manifiesto del pod.&lt;/p>
&lt;p>La regla operativa es brutalmente simple: &lt;strong>en time-slicing, el presupuesto de VRAM lo gestionas tú a mano, sumando los &lt;code>--gpu-memory-utilization&lt;/code>&lt;/strong>. El número de réplicas controla cuántos pods &lt;em>caben por turnos de cómputo&lt;/em>, pero &lt;strong>no reserva ni un byte de memoria&lt;/strong>. Confundir las dos cosas es el error recurrente.&lt;/p>
&lt;h2 id="mps-cocineros-coordinados-en-la-misma-encimera">MPS: cocineros coordinados en la misma encimera&lt;/h2>
&lt;p>El &lt;strong>Multi-Process Service&lt;/strong> (&lt;a href="https://docs.nvidia.com/deploy/mps/index.html">MPS&lt;/a>) ataca un problema distinto. Por defecto, cuando varios procesos usan la misma GPU sin MPS, cada uno tiene su propio &lt;strong>contexto CUDA&lt;/strong>, y la GPU &lt;strong>alterna&lt;/strong> entre contextos (time-slicing a nivel de driver): no ejecutan kernels a la vez, se turnan, con overhead de cambio de contexto. Si tus kernels son pequeños y no llenan la GPU ellos solos, esto deja SMs ociosos: el proceso A usa el 30 % de los SMs durante su turno y el otro 70 % se desperdicia.&lt;/p>
&lt;p>MPS introduce un &lt;strong>daemon&lt;/strong> que comparte un único contexto CUDA entre procesos, de modo que sus kernels pueden ejecutarse &lt;strong>concurrentemente&lt;/strong> ocupando SMs distintos &lt;strong>a la vez&lt;/strong>. Es reparto &lt;strong>espacial&lt;/strong> de cómputo: en lugar de turnarse la encimera entera, cada cocinero ocupa una parte y trabajan en paralelo. Esto reduce el overhead de context-switch y &lt;strong>sube el throughput cuando hay muchos kernels pequeños concurrentes&lt;/strong> que individualmente no saturan la GPU.&lt;/p>
&lt;p>Y, a diferencia del time-slicing puro, MPS permite &lt;strong>poner límites por proceso&lt;/strong>, lo que da una forma de QoS:&lt;/p>
&lt;ul>
&lt;li>&lt;code>CUDA_MPS_ACTIVE_THREAD_PERCENTAGE&lt;/code> limita el &lt;strong>porcentaje de SMs&lt;/strong> que un cliente MPS puede usar. Por defecto cada cliente recibe $100 / \text{MaxSharedClients}$. Fijarlo a, digamos, 40 % cierra el techo de cómputo de ese proceso (&lt;a href="https://docs.nvidia.com/deploy/mps/appendix-tools-and-interface-reference.html">docs MPS&lt;/a>).&lt;/li>
&lt;li>&lt;code>CUDA_MPS_PINNED_DEVICE_MEM_LIMIT&lt;/code> impone un &lt;strong>tope de memoria&lt;/strong> por cliente (válido desde CUDA 11.5). Esto es lo que el time-slicing &lt;strong>no&lt;/strong> tiene: un límite de VRAM por proceso que el runtime hace cumplir.&lt;/li>
&lt;/ul>
&lt;p>Estos dos límites convierten a MPS en un mecanismo de &lt;strong>provisioning de recursos&lt;/strong> que mitiga el &lt;em>noisy neighbor&lt;/em>: puedes garantizar que un proceso no se coma más del X % de SMs ni más de Y GB. La combinación da una QoS razonable —no perfecta, pero real.&lt;/p>
&lt;p>La limitación que MPS &lt;strong>no&lt;/strong> resuelve: &lt;strong>el aislamiento de fallos es débil&lt;/strong>. Como los clientes comparten el contexto CUDA del daemon, un error fatal en un cliente puede afectar al daemon y, por tanto, a los demás clientes (históricamente, un cliente que muere de forma sucia podía requerir reiniciar el daemon). Es mejor que el time-slicing en este aspecto, pero está lejos del aislamiento por hardware. Por eso MPS encaja cuando hay &lt;strong>confianza entre las cargas&lt;/strong> —procesos de tu propio equipo, no tenants ajenos.&lt;/p>
&lt;p>El caso de uso canónico: &lt;strong>muchas peticiones de inferencia pequeñas y concurrentes&lt;/strong> que individualmente dejan la GPU medio vacía. MPS las solapa y sube el throughput agregado. Servir varios modelos pequeños o varias réplicas ligeras del mismo modelo en una GPU de datacenter, donde confías en todas las cargas, es territorio MPS.&lt;/p>
&lt;h2 id="mig-paredes-de-hormigón">MIG: paredes de hormigón&lt;/h2>
&lt;p>El &lt;strong>Multi-Instance GPU&lt;/strong> (&lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/">MIG&lt;/a>) es el único de los tres que da &lt;strong>aislamiento de verdad&lt;/strong>, porque corta la GPU &lt;strong>en hardware&lt;/strong>. Disponible en las GPU de datacenter modernas —A100 (Ampere), H100/H200 (Hopper), B200 (Blackwell)— y &lt;strong>nunca&lt;/strong> en las de consumo: una RTX 5090 (Blackwell de consumo) &lt;strong>no soporta MIG&lt;/strong>, igual que las GeForce en general.&lt;/p>
&lt;p>MIG divide la GPU en hasta &lt;strong>siete instancias&lt;/strong> (&lt;em>GPU Instances&lt;/em>), y cada instancia recibe una porción &lt;strong>dedicada&lt;/strong> de:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>SMs&lt;/strong> (compute slices): el cómputo se reparte en 7 &lt;em>slices&lt;/em>, cada uno ~1/7 de los SMs.&lt;/li>
&lt;li>&lt;strong>L2 cache y memoria&lt;/strong>: cada instancia tiene su trozo de HBM y su porción de caché L2.&lt;/li>
&lt;li>&lt;strong>Ancho de banda de memoria&lt;/strong>: dedicado, no compartido.&lt;/li>
&lt;li>&lt;strong>Caminos de datos y motores&lt;/strong>: con barreras de fallo entre instancias.&lt;/li>
&lt;/ul>
&lt;p>El resultado es que una instancia MIG se comporta como &lt;strong>una GPU más pequeña e independiente&lt;/strong>: lo que pase en una —un OOM, un kernel que peta, una carga que satura su cómputo— &lt;strong>no afecta&lt;/strong> a las vecinas. Aislamiento de memoria, de fallo y de rendimiento (QoS), las tres cosas que el time-slicing no da y que MPS solo da a medias.&lt;/p>
&lt;h3 id="los-perfiles-de-la-h100-80gb">Los perfiles de la H100 80GB&lt;/h3>
&lt;p>MIG no permite tamaños arbitrarios: tiene &lt;strong>perfiles fijos&lt;/strong>. En la H100 80GB, el &lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/supported-mig-profiles.html">catálogo de perfiles&lt;/a> (notación &lt;code>&amp;lt;compute&amp;gt;g.&amp;lt;memoria&amp;gt;gb&lt;/code>) es:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Perfil&lt;/th>
&lt;th>Compute (slices)&lt;/th>
&lt;th>Memoria&lt;/th>
&lt;th>Instancias máx.&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>1g.10gb&lt;/code>&lt;/td>
&lt;td>1/7&lt;/td>
&lt;td>10 GB&lt;/td>
&lt;td>7&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>1g.20gb&lt;/code>&lt;/td>
&lt;td>1/7&lt;/td>
&lt;td>20 GB&lt;/td>
&lt;td>4&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>2g.20gb&lt;/code>&lt;/td>
&lt;td>2/7&lt;/td>
&lt;td>20 GB&lt;/td>
&lt;td>3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>3g.40gb&lt;/code>&lt;/td>
&lt;td>3/7&lt;/td>
&lt;td>40 GB&lt;/td>
&lt;td>2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>4g.40gb&lt;/code>&lt;/td>
&lt;td>4/7&lt;/td>
&lt;td>40 GB&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>7g.80gb&lt;/code>&lt;/td>
&lt;td>7/7&lt;/td>
&lt;td>80 GB&lt;/td>
&lt;td>1 (GPU entera)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>(Existe además &lt;code>1g.10gb+me&lt;/code>, una variante con &lt;em>media engines&lt;/em> para codificación de vídeo.) La unidad base de memoria en la H100 80GB es de &lt;strong>10 GB por slice&lt;/strong> (80 GB / 8, con un slice reservado), y la de cómputo es 1/7 de los SMs. Los perfiles combinan estas unidades. Fíjate en &lt;code>1g.20gb&lt;/code>: misma fracción de cómputo que &lt;code>1g.10gb&lt;/code> (1/7 de SMs) pero &lt;strong>el doble de memoria&lt;/strong> —útil cuando una carga necesita más VRAM que cómputo.&lt;/p>
&lt;p>Un detalle importante: las particiones MIG no se mezclan libremente. La GPU se divide siguiendo una geometría válida (los perfiles encajan como piezas en una rejilla), y los perfiles &lt;strong>se fijan al configurar&lt;/strong> la GPU; cambiarlos requiere drenar y reparticionar. Son paredes de hormigón: sólidas, pero no se mueven en caliente.&lt;/p>
&lt;h3 id="el-cálculo-71g10gb-frente-a-17g80gb">El cálculo: 7×1g.10gb frente a 1×7g.80gb&lt;/h3>
&lt;p>Comparemos los dos extremos. A la izquierda, &lt;strong>siete instancias &lt;code>1g.10gb&lt;/code>&lt;/strong>: siete GPU aisladas de 10 GB cada una. A la derecha, &lt;strong>una sola &lt;code>7g.80gb&lt;/code>&lt;/strong>: la H100 entera sin particionar.&lt;/p>
&lt;p>La pregunta operativa es &lt;strong>qué cabe en 10 GB&lt;/strong>. El presupuesto de VRAM de una instancia se reparte entre pesos del modelo y KV-cache:&lt;/p>
&lt;p>$$V_{\text{inst}} = V_{\text{pesos}} + V_{\text{KV}} + V_{\text{overhead}}$$&lt;/p>
&lt;p>Tomemos un modelo de &lt;strong>7B parámetros en FP8&lt;/strong> (1 byte/parámetro):&lt;/p>
&lt;p>$$V_{\text{pesos}} \approx 7 \times 10^9 \times 1\ \text{byte} = 7\ \text{GB}$$&lt;/p>
&lt;p>En una instancia &lt;code>1g.10gb&lt;/code> (10 GB), tras los 7 GB de pesos y restando ~0.5–1 GB de overhead del runtime, quedan &lt;strong>~2 GB para KV-cache&lt;/strong>. Eso da para una ventana de contexto modesta y poca concurrencia —correcto para un servicio guardrail, un clasificador o un modelo de extracción que procesa prompts cortos uno a uno. Un 7B en INT4 (~3.5 GB de pesos) deja ~5.5 GB de KV-cache, mucho más holgado. Pero un modelo de 13B en FP8 (~13 GB de pesos) &lt;strong>no cabe&lt;/strong> en una instancia de 10 GB: ni siquiera entran los pesos. Para él necesitas &lt;code>1g.20gb&lt;/code>, &lt;code>2g.20gb&lt;/code> o mayor.&lt;/p>
&lt;p>Frente a esto, la &lt;code>7g.80gb&lt;/code> (GPU entera) te da los 80 GB para &lt;strong>un modelo grande&lt;/strong>: un 70B en FP8 (~70 GB de pesos) cabe con KV-cache justo, o un 70B con más holgura repartido en &lt;em>tensor-parallel&lt;/em> sobre varias GPU enteras (ver &lt;a href="https://blog.lo0.es/posts/tp-replicas-una-grande-vs-n-pequenas/">TP frente a réplicas: una grande contra N pequeñas&lt;/a>).&lt;/p>
&lt;p>La lectura es clara: &lt;strong>particionar fino (7×1g.10gb) maximiza el número de cargas aisladas pequeñas; no particionar (1×7g.80gb) maximiza el tamaño del modelo que cabe.&lt;/strong> El KV-cache disponible por instancia se reduce proporcionalmente al particionar, así que MIG fino sirve para &lt;strong>muchos servicios ligeros aislados&lt;/strong>, no para un modelo grande troceado. Si tu carga es un solo modelo grande, MIG no es para ti —usa la GPU entera o varias en TP.&lt;/p>
&lt;h2 id="el-árbol-de-decisión">El árbol de decisión&lt;/h2>
&lt;p>Las tres preguntas, en orden:&lt;/p>
&lt;pre tabindex="0">&lt;code>¿Necesitas aislamiento REAL?
(multi-tenant, compliance, fallo de una carga no debe tocar otra)
│
┌────┴────┐
SÍ NO
│ │
¿Es Hopper/ ¿Muchos kernels PEQUEÑOS concurrentes
Ampere/ Y confías en todas las cargas?
Blackwell? │
│ ┌────┴────┐
┌──┴──┐ SÍ NO
SÍ NO │ │
│ │ MPS ¿Dev / ráfagas / GPU de consumo
MIG │ (espacial, / sin necesidad de aislar?
│ │ QoS por │
│ no hay proceso) SÍ
│ aislam. │
│ real: TIME-SLICING
│ replantea (temporal, barato,
│ (mueve a funciona en 5090)
│ CPU, otra GPU,
│ o asume riesgo
│ con time-slicing)
&lt;/code>&lt;/pre>&lt;p>Y en una frase cada rama:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>MIG&lt;/strong> cuando el aislamiento es un requisito (compliance, multi-tenant, SLA duro) &lt;strong>y&lt;/strong> tienes hardware de datacenter que lo soporta. Las paredes de hormigón cuestan, pero si las necesitas no hay sustituto.&lt;/li>
&lt;li>&lt;strong>MPS&lt;/strong> cuando tienes muchas cargas pequeñas concurrentes que dejan la GPU medio vacía &lt;strong>y&lt;/strong> confías en todas (mismo equipo, no tenants ajenos). Subes throughput con QoS razonable, asumiendo aislamiento de fallos imperfecto.&lt;/li>
&lt;li>&lt;strong>Time-slicing&lt;/strong> cuando es dev, ráfagas, baja utilización, GPU de consumo, o simplemente no necesitas aislar nada. Barato y universal, pero gestiona el presupuesto de VRAM a mano.&lt;/li>
&lt;/ul>
&lt;p>Un matiz que la documentación reciente recoge: &lt;strong>se pueden combinar&lt;/strong>. Puedes hacer time-slicing &lt;em>sobre&lt;/em> una instancia MIG (aislamiento de hardware en la frontera de la instancia, turnos de software dentro), o usar MPS dentro de una instancia MIG. Las capas no son excluyentes; el árbol elige la &lt;strong>estrategia primaria&lt;/strong>.&lt;/p>
&lt;h2 id="aplicado-al-cluster-genérico-4h100">Aplicado al cluster genérico 4×H100&lt;/h2>
&lt;p>Bajemos a números con un cluster on-premise genérico de &lt;strong>4×H100 SXM 80 GB con NVLink&lt;/strong>. Es habitual tener un menú de cargas heterogéneo: un modelo grande de chat, servicios ligeros (embeddings, reranker, guardrails) y una cola de dev/experimentación. Cada tipo pide un mecanismo distinto. Un reparto razonado:&lt;/p>
&lt;p>&lt;strong>GPU 0 y GPU 1 — modelo grande en tensor-parallel (sin compartir).&lt;/strong> Un modelo de 70B en FP8 ocupa ~70 GB de pesos; servido cómodo con KV-cache generoso necesita más de una H100. Lo repartimos en &lt;em>tensor-parallel&lt;/em> sobre &lt;strong>dos H100 enteras&lt;/strong> unidas por NVLink (el ancho de banda intra-nodo es lo que hace viable el TP; el detalle está en &lt;a href="https://blog.lo0.es/posts/tp-replicas-una-grande-vs-n-pequenas/">TP frente a réplicas&lt;/a>). Aquí &lt;strong>no compartimos&lt;/strong>: estas dos GPU son del modelo grande y punto. Aislamiento total por dedicación.&lt;/p>
&lt;p>$$V_{\text{disponible}} = 2 \times 80 = 160\ \text{GB};\quad V_{\text{pesos}} \approx 70\ \text{GB};\quad V_{\text{KV}} \approx 80\ \text{GB de KV-cache}$$&lt;/p>
&lt;p>Sobra memoria para una cola de peticiones larga y mucha concurrencia.&lt;/p>
&lt;p>&lt;strong>GPU 2 — partida con MIG en instancias pequeñas para servicios ligeros.&lt;/strong> Embeddings (&lt;code>bge-m3&lt;/code>), reranker (&lt;code>bge-reranker-v2-m3&lt;/code>) y un par de modelos guardrail (1B–3B) son cargas distintas, de equipos potencialmente distintos, y quieres que un fallo o un pico en una &lt;strong>no toque&lt;/strong> a las demás. Multi-tenant ligero con aislamiento → &lt;strong>MIG&lt;/strong>. Una partición razonable de la H100:&lt;/p>
&lt;p>$$\underbrace{3 \times \texttt{1g.10gb}}&lt;em>{\text{30 GB, 3/7 SMs}} ;+; \underbrace{1 \times \texttt{4g.40gb}}&lt;/em>{\text{40 GB, 4/7 SMs}}$$&lt;/p>
&lt;p>Las tres &lt;code>1g.10gb&lt;/code> (10 GB, 1/7 SMs cada una) alojan embeddings, reranker y un guardrail 1B INT4 —cada uno aislado, sin &lt;em>noisy neighbor&lt;/em>. La &lt;code>4g.40gb&lt;/code> (40 GB, 4/7 SMs) aloja un modelo intermedio de 7B–13B con KV-cache decente para un servicio de apoyo. Cada servicio tiene su despensa y su pared; si el reranker peta, el chat no se entera.&lt;/p>
&lt;p>&lt;strong>GPU 3 — time-slicing para dev y ráfagas.&lt;/strong> Los desarrolladores tocan la GPU esporádicamente: experimentos, fine-tunes cortos, pruebas de modelos. No necesitan aislamiento (es el mismo equipo) y rara vez coinciden activos. La anunciamos como &lt;strong>4 réplicas&lt;/strong> vía device-plugin. Cuatro pods de dev caben por turnos. Presupuesto de VRAM con la fórmula de arriba: si cada dev levanta un vLLM a &lt;code>--gpu-memory-utilization 0.20&lt;/code>, suman $4 \times 16 = 64$ GB &amp;lt; 80 GB, sin OOM. Si alguien necesita más, baja el número de réplicas o coordina con el equipo —el coste de la flexibilidad es la disciplina manual.&lt;/p>
&lt;p>&lt;strong>Resumen del reparto:&lt;/strong>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Recurso&lt;/th>
&lt;th>Mecanismo&lt;/th>
&lt;th>Carga&lt;/th>
&lt;th>Aislamiento&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>GPU 0 + GPU 1&lt;/td>
&lt;td>Dedicación (TP)&lt;/td>
&lt;td>70B chat en tensor-parallel&lt;/td>
&lt;td>total (dedicado)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GPU 2&lt;/td>
&lt;td>MIG (3×1g.10gb + 1×4g.40gb)&lt;/td>
&lt;td>embeddings, reranker, guardrails, 7B–13B&lt;/td>
&lt;td>hardware real&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GPU 3&lt;/td>
&lt;td>Time-slicing (4 réplicas)&lt;/td>
&lt;td>dev, ráfagas, experimentos&lt;/td>
&lt;td>ninguno (confianza)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>La lógica es siempre la misma: &lt;strong>gasta aislamiento (MIG) donde lo necesitas, gasta concurrencia barata (time-slicing) donde no, y reserva las GPU enteras para lo que de verdad las llena.&lt;/strong> Una H100 sirviendo embeddings con &lt;code>7g.80gb&lt;/code> sería tan absurdo como una RTX 5090 intentando MIG: la herramienta no encaja con la carga.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto">Lo que no hemos cubierto&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Qué pasa cuando ni siquiera caben a la vez&lt;/strong>: si tienes más modelos que VRAM y hay que turnarlos &lt;em>en memoria&lt;/em> (cargar/descargar pesos, no solo turnar cómputo), entras en territorio de &lt;em>swap&lt;/em> y &lt;em>sleep&lt;/em> —la pieza hermana &lt;a href="https://blog.lo0.es/posts/servir-varios-modelos-una-gpu-swap-sleep/">Servir varios modelos en una GPU&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Scheduling NUMA-aware&lt;/strong>: en nodos multi-socket, qué GPU toca a qué CPU/memoria importa para la latencia; ver &lt;a href="https://blog.lo0.es/posts/kubelet-resource-managers-rke2-numa/">Kubelet resource managers en RKE2&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Autoscaling de las réplicas&lt;/strong>: cuántas instancias levantar según carga real, con KEDA y métricas de cola; ver &lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling de LLM en Kubernetes con KEDA&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Benchmark de jitter bajo contención&lt;/strong>: cuánto baila realmente el TTFT en time-slicing con 4 réplicas activas frente a MIG —material que merece medición propia, no estimación.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/finops-multi-tenancy-gpu-litellm/">FinOps y multi-tenancy del cluster GPU: quién paga qué&lt;/a> — MIG como base del aislamiento y la atribución de coste entre tenants.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/gitops-stack-inferencia-llm-flux/">GitOps del stack de inferencia con Flux: operar el asistente como código&lt;/a> — cómo se declara el reparto de GPU (MIG, gpu-memory-utilization) como código en GitOps.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/servir-varios-modelos-una-gpu-swap-sleep/">Servir varios modelos en una GPU: swap y sleep&lt;/a> — pieza hermana de la serie: cuando los modelos no caben a la vez en VRAM y hay que turnarlos en memoria, no solo en cómputo.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/kubelet-resource-managers-rke2-numa/">Kubelet resource managers en RKE2: NUMA y topología&lt;/a> — el reparto de GPU se complica con afinidad NUMA; qué GPU asignar a qué socket para no pagar latencia de interconexión.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/tp-replicas-una-grande-vs-n-pequenas/">TP frente a réplicas: una grande contra N pequeñas&lt;/a> — la decisión de dedicar 2 H100 enteras en tensor-parallel para el modelo grande es justo lo que aquí asumimos en el reparto del cluster.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/capacity-planning-inferencia-llm-on-premise/">Capacity planning para inferencia LLM on-premise&lt;/a> — el presupuesto de VRAM (pesos + KV-cache) que aquí trabajamos por instancia es el núcleo del sizing del cluster entero.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling de LLM en Kubernetes con KEDA&lt;/a> — cuántas réplicas (time-sliced o no) levantar según la carga real, en lugar de fijarlas a mano.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://blog.lo0.es/posts/cinco-niveles-madurez-plataforma-llm-on-premise/">Cinco niveles de madurez de una plataforma LLM on-premise&lt;/a> — pasar de &amp;ldquo;una GPU, una carga&amp;rdquo; a compartir con aislamiento es uno de los saltos de madurez que marca el modelo.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>NVIDIA — &lt;em>Time-Slicing GPUs in Kubernetes&lt;/em> (GPU Operator). &lt;a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html">https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Multi-Process Service (MPS) Overview&lt;/em>. &lt;a href="https://docs.nvidia.com/deploy/mps/index.html">https://docs.nvidia.com/deploy/mps/index.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>MPS: Tools and Interface Reference&lt;/em> (&lt;code>CUDA_MPS_ACTIVE_THREAD_PERCENTAGE&lt;/code>, &lt;code>CUDA_MPS_PINNED_DEVICE_MEM_LIMIT&lt;/code>). &lt;a href="https://docs.nvidia.com/deploy/mps/appendix-tools-and-interface-reference.html">https://docs.nvidia.com/deploy/mps/appendix-tools-and-interface-reference.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Multi-Instance GPU (MIG) User Guide&lt;/em>. &lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/">https://docs.nvidia.com/datacenter/tesla/mig-user-guide/&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Supported MIG Profiles&lt;/em> (catálogo H100 80GB). &lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/supported-mig-profiles.html">https://docs.nvidia.com/datacenter/tesla/mig-user-guide/supported-mig-profiles.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>k8s-device-plugin&lt;/em> (réplicas de time-slicing). &lt;a href="https://github.com/NVIDIA/k8s-device-plugin">https://github.com/NVIDIA/k8s-device-plugin&lt;/a>&lt;/li>
&lt;li>vLLM — &lt;em>Engine Arguments&lt;/em> (&lt;code>--gpu-memory-utilization&lt;/code>). &lt;a href="https://docs.vllm.ai/en/latest/serving/engine_args.html">https://docs.vllm.ai/en/latest/serving/engine_args.html&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>