¿Cabe este modelo en mi ordenador?
La memoria que necesita un modelo es el espacio de sus números más el espacio del texto que está leyendo. Puedes calcularla con una cuenta corta antes de descargar nada.
Importa porque un modelo que no cabe no arranca. Una estimación errónea te quita una tarde y a veces el precio de un equipo mayor.
Al final de esta lección
Nota
Puedo calcular cuánta memoria necesita un modelo.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Parámetro | un número que el modelo aprendió | |
| Pesos | todos los parámetros juntos | |
| Precisión | cuántos bits guardan cada número | 16 bits |
| Caché | memoria con el texto leído hasta ahora | |
| Gigabyte (GB) | mil millones de bytes |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Los pesos son parámetros por bytes
Un modelo es sobre todo una lista larguísima de números. Cada número es un parámetro. Cada parámetro se guarda con unos cuantos bits, y 8 bits forman un byte.
Así que los pesos ocupan los parámetros por los bytes de cada uno. Un modelo de 8 mil millones de parámetros a 16 bits (2 bytes) necesita 16 gigabytes solo para sus pesos.
Los identificadores del código van en inglés, como los nombres de las funciones de Python.
Modelo A, solo los pesos
| Precisión | Bytes por número | Pesos de 8 mil millones |
|---|---|---|
| 32 bits | 4 | 32 GB |
| 16 bits | 2 | 16 GB |
| 8 bits | 1 | 8 GB |
| 4 bits | 0,5 | 4 GB |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un texto largo añade una caché
Mientras lee, el modelo guarda notas de cada token anterior. Esas notas son la caché. Un token necesita 2 por las capas, por el ancho y por los bytes.
Para el Modelo A son 2 x 32 x 1024 x 2 = 131 072 bytes por token. Con 8000 tokens la caché es de 1 GB aproximadamente. La caché crece con el texto y los pesos no.
Modelo A, caché según el texto
| Tokens del texto | Caché |
|---|---|
| 1000 | 0,13 GB |
| 8000 | 1,05 GB |
| 32 000 | 4,19 GB |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente cree que un modelo que pesa 16 GB al descargarlo necesita 16 GB para funcionar. Los pesos son solo una parte. La caché crece con el texto y el equipo necesita memoria libre. Suma la caché y deja libre una quinta parte.
Escribe el ayudante del modelo, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el ayudante del modelo, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"estado \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el calculador de memoria, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const model = { billions: 8, layers: 32, kvWidth: 1024 };' 'const BITS = [32, 16, 8, 4];' 'function weightsGB(bits) {' ' return model.billions * bits / 8;' '}' > mem.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el calculador de memoria, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function cacheGB(tokens) {' ' const perToken = 2 * model.layers * model.kvWidth * 2;' ' return perToken * tokens / 1000000000;' '}' >> mem.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el calculador de memoria, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"Modelo A: 8 mil millones de parámetros, caché a 16 bits\");' ' for (const bits of BITS) {' ' const total = weightsGB(bits) + cacheGB(8000);' ' console.log(bits + \" bits: pesos \" + weightsGB(bits) + \" GB, total \" + total.toFixed(2) + \" GB\");' ' }' ' console.log(\"Caché con 1000 tokens: \" + cacheGB(1000).toFixed(2) + \" GB\");' ' console.log(\"Caché con 32000 tokens: \" + cacheGB(32000).toFixed(2) + \" GB\");' >> mem.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el calculador de memoria, parte 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' const q = \"En una frase corta, ¿por qué un texto más largo necesita más memoria?\";' ' const sample = \"Cada token del texto añade una nota a la caché del modelo, así que un texto más largo ocupa una caché mayor.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> mem.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta el calculador de memoria
docker exec -w /home/node/project agent node mem.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
No se descarga nada
Este laboratorio no tiene GPU ni archivos de modelos. El Modelo A es inventado y cada tamaño es una cuenta. La llamada corta al modelo del laboratorio solo redacta una frase.
Si ningún modelo responde, el Run imprime antes Muestra grabada, y las cuentas son las mismas.
Qué imprime el Run
| Línea | Qué muestra |
|---|---|
| 32 bits: pesos 32 GB, total 33.05 GB | El tamaño completo no cabe en un equipo pequeño |
| 4 bits: pesos 4 GB, total 5.05 GB | Con menos bits, mucha menos memoria |
| Caché con 32000 tokens: 4.19 GB | Un texto largo tiene un coste real |
| el modelo dijo: ... | Una frase. Las palabras cambian en cada ejecución |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.