Me gusta intentar inesperaciones de vez en cuando, dirigir una tarea en una plataforma inesperada o escribirla en un lenguaje inapropiado, solo para hacer ejercicio.
Con el entusiasmo actual por la IA y especialmente por LLM (Large Language Model), me sedujo la idea de dirigir uno de estos modelos en una plataforma no planeada para esto: una Raspberry Pi.
Elegí el modelo Raspberry Pi 5, el más potente hasta ahora con 8 Gb de RAM. Esto es por dos razones: el funcionamiento de un LLM es obviamente muy codiófico en CPU y recursos de memoria, y por otro lado la implementación que elegí sólo obras en la arquitectura x86 y en Arm64. Por lo tanto, es necesario tener un Raspberry Pi soportando un sistema operativo de 64 bits. Un Pi 4 podría haber sido suficiente, pero creo que su tamaño de memoria es demasiado limitado.
Para este experimento, tuve un objetivo subyacente: comprobar si un modelo de lenguaje es razonablemente utilizable en un sistema relativamente pequeño (siempre que se pueda calificar un Raspberry Pi 5 con 8 GB de RAM como un entorno restringido) con una conexión a Internet de baja velocidad, o incluso inexistente. Se trata de integrar un LLM en sistemas integrados basados en Linux, para proyectos de clientes o sesiones de capacitación.
Ponemos el marco de esta prueba: se trata de ejecutar el modelo de lenguaje localmente en el Raspberry Pi, no consultar un servidor en la nube.
Hay muchos modelos de idiomas disponibles más o menos libremente. Algunos requieren una suscripción y la obtención de una clave de API (Gemini de Google, Claude d'Anthropic, GPT de OpenAI, etc.).
Una solución que mejor se adapte a mis expectativas es el uso de Ollama, una herramienta de licencia libre (MIT), capaz de cargar y ejecutar LLMs en Linux, Windows y MacOS.
Instalé la última versión de Raspberry Pi OS (04/07/2024) en versión de 64 bits basada en una distribución de Debian 12.
La instalación de Ollama es extremadamente sencilla: un script para descargar y ejecutar.
El sitio Ollama sugiere usar el siguiente comando que descarga el script y lo envía directamente como entrada a una shell.
$ curl -fsSL https://ollama.com/install.sh | sh
Preferiría mirar el contenido del guión antes de ejecutarlo, así que me fui por cierto:
cpb@raspberrypi:~ $ curl https://ollama.ai/install.sh > install.sh [...] cpb@raspberrypi:~ $ chmod +x install.sh
Después de mirar rápidamente el contenido del script, lo instalo de la siguiente manera:
cpb@raspberrypi:~ $ ./install.sh >>> Downloading ollama... ####################################################################################################################################################> >>> Installing ollama to /usr/local/bin... >>> Creating ollama user... >>> Adding ollama user to render group... >>> Adding ollama user to video group... >>> Adding current user to ollama group... >>> Creating ollama systemd service... >>> Enabling and starting ollama service... Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service. >>> The Ollama API is now available at 127.0.0.1:11434. >>> Install complete. Run "ollama" from the command line. WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.
El script nos advierte que no ha encontrado procesadores gráficos de Nvidia o Amd (GPUs). No es de extrañar en un Raspberry Pi. Y como resultado, hará todo el tratamiento directamente en los corazones de la CPU.
La página de Ollama Models contiene unos cien modelos de idiomas disponibles. La mayoría están disponibles en dos o tres versiones dependiendo del tamaño de la red neuronal utilizada. Tomemos el ejemplo del modelo phi3
::
Ambas versiones 3B
(3 billones, 3.000 millones) y 14B
(14 billones, 14.000 millones) correspondientes al número de paramètres"parámetros" del modelo, es decir, aproximadamente el número de conexiones entre las neuronas de la red. Cuanto mayor sea este número, mayor serán las posibilidades del LLM. Pero al aumentar el número de parámetros, el espacio de memoria necesario para acomodarse aumenta y los recursos computacionales (potencia CPU, consumo de energía) esenciales para viajar también crecen.
Con un Raspberry Pi con 8 GB de memoria RAM, no tiene sentido esperar ejecutar modelos de más de 7 mil millones de parámetros, pero todavía deja una buena selección de modelos.
El primer modelo que estoy probando es el Phi-3, de disponible bajo una licencia del MIT. Existe en dos versiones: 3.800 millones y 14.000 millones. Esta es, por supuesto, la primera versión que voy a usar. Para instalarlo, se pueden utilizar los nombres. phi3:3.8b
o o phi3:mini
::
cpb@raspberrypi:~ $ ollama pull phi3:mini pulling manifest pulling manifest pulling 3e38718d00bb... 100% ▕█████████████████████████████████████████████████████▏ 2.2 GB > pulling fa8235e5b48f... 100% ▕█████████████████████████████████████████████████████▏ 1.1 KB > pulling 542b217f179c... 100% ▕█████████████████████████████████████████████████████▏ 148 B > pulling 8dde1baf1db0... 100% ▕█████████████████████████████████████████████████████▏ 78 B > pulling ed7ab7698fdd... 100% ▕█████████████████████████████████████████████████████▏ 483 B > verifying sha256 digest writing manifest removing any unused layers success
Después de dos minutos, el modelo se graba en la tarjeta SD del Raspberry Pi, listo para su uso. Vamos a probarlo con una simple pregunta:
cpb@raspberrypi:~ $ ollama run phi3:mini >>> Send a message (/? for help)
Ollama tardaba unos diez segundos en cargar e inicializar el modelo, antes de invitarnos a hacerle una pregunta.
>>> What is a raspberry pi? A Raspberry Pi is a small, affordable single-board computer developed by the Raspberry Pi Foundation in the UK. Its purpose is to promote teaching basic computer science in schools and developing digital skills among learners globally, especially those who may lack access to such resources due to economic or other barriers. The device boasts various processor options compatible with a full operating system like Linux, as well as peripherals that allow it to be used for projects ranging from media centers to home automation devices and robotics kits. It has 1-2 USB ports along with audio/video output capabilities and provides enough computational power for educational purposes or simple personal computing tasks through a Linux operating system loaded onto its microSD card, which can be installed via the Raspberry Pi Imager toolkit on Windows PCs, Macs, and some other devices. The device measures just over 60mm by 30mm with dimensions similar to those of an SDHC memory card while weighing only about as much (around 24 grams). It is powered through a micro USB port on the board which can be connected directly into a wall adapter or use battery packs, offering convenience and flexibility. Raspberry Pi has evolved with several generations of boards: The first generation Raspberry Pi started in 2012; followed by second (released in February 2tyr3), third (Wavesby released in December 2014, also known as the Model B+ and later renamed to "Model B"), fourth gen ("Bullseye", January 2018) which includes Raspberry Pi Zero W; latest fifth generation releases are Broadcom system-on-chip based boards (released in April & September of 2022 as"Centenary") with an emphasis on speed and power efficiency. Raspberry Pis also come in different versions, such as the Raspberry Pi Model A which is smaller than its counterparts but has fewer I/O pins; there's even a version that comes without HDMI output called "Zero" or Zero W, released later with Wi-Fi capabilities. Raspberry Pi can be used for various applications such as home automation projects like smart lighting systems and security cameras to robotics kits where it acts as the main processing unit of a small drone; educational purposes include learning about programming languages (like Python) or even creating simple games, multimedia players, etc. Aside from being used in various personal computing applications for hobbyists, researchers and developers are using Raspberry Pi to create low-cost solutions such as smart city devices like traffic sensors; environmental monitoring systems that measure air quality levels among many other things which showcase the versatility of this small but mighty computer. >>> Send a message (/? for help)
Bastante hablador de este modelo. Tomó poco más de tres minutos para escribir este texto. Como la exhibición se hizo en secuencias cercanas al tamaño de una palabra, esto corresponde a la velocidad de un discurso tranquilo. Podríamos alimentar a un sintetizador de voz a este ritmo y tener una buena charla.
Mientras duplicaba la cantidad y calidad de la respuesta, reiniciaba el Raspberry Pi desconectándola físicamente de la red y repesté la misma pregunta que condujo a una respuesta ligeramente diferente, pero en sustancia bastante cerca de la imagen siguiente:
Tras dejar Ollama con la orden /bye
Vamos a hacer un pequeño experimento.
>>> Send a message (/? for help) >>> /bye cpb@raspberrypi:~ $
Cuando comenzó, Ollama instaló un servicio en el puerto TCP 11434 del Raspberry Pi que ofrece una API de descanso para interactuar con él. Vamos a interrogarlo desde la concha del mismo Raspberry Pi, con el mando curl
.
También aprovecharemos la oportunidad para hacerle una pregunta en francés.
cpb@raspberrypi:~ $ curl http://localhost:11434/api/generate -d '{ "model": "phi3:mini", "prompt": "Quelle est la quatrième planète du système solaire ?" }'
Durante los siguientes minutos, recibimos respuestas de Ollama, que poco a poco vano construye el contenido de su respuesta. Los mensajes están estampados en el tiempo, el campo de respuesta de cada línea contiene la porción de texto y el campo de done"done- es para "false", para indicar que la respuesta no está completa. Marco el campo de la respuesta en negrita para que su contenido sea legible:
{"model":"phi3:mini","created_at":"2024-07-21T05:43:17.084478429Z","response":" La","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:17.369720015Z","response":" qu","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:17.628725439Z","response":"atri","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:17.887893364Z","response":"ème","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:18.146665529Z","response":" plan","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:18.405267322Z","response":"ète","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:18.664291747Z","response":" du","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:18.923346486Z","response":" système","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:19.181757649Z","response":" sol","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:19.4407295Z","response":"aire","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:19.699538905Z","response":",","done":false} [...] {"model":"phi3:mini","created_at":"2024-07-21T05:43:25.058321233Z","response":" est","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:25.329659597Z","response":" Mars","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:43:25.600804776Z","response":".","done":false} [...]
Después de unos momentos, Phi-3 se detiene sin darnos una clase de geografía marciana y termina con un mensaje final cuyo campo done"doed-----
{"model":"phi3:mini","created_at":"2024-07-21T05:44:03.022767578Z","response":" les","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:03.331061632Z","response":" plus","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:03.639537317Z","response":" grandes","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:03.948115316Z","response":" structures","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:04.257345336Z","response":" ro","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:04.565302908Z","response":"che","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:04.874108446Z","response":"uses","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:05.182596871Z","response":" conn","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:05.490781443Z","response":"ues","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:05.799564851Z","response":" dans","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:06.10923715Z","response":" le","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:06.447442283Z","response":" système","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:06.755825597Z","response":" sol","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:07.064675857Z","response":"aire","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:07.373813932Z","response":" :","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:07.681658855Z","response":" les","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:07.990091225Z","response":" can","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:08.306772505Z","response":"y","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:08.623075266Z","response":"ons","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:08.940534344Z","response":" Olymp","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:09.257847867Z","response":"us","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:09.574017294Z","response":" M","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:09.890405092Z","response":"ons","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:10.206899964Z","response":" et","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:10.523604097Z","response":" Vall","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:10.840915693Z","response":"es","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:11.157677085Z","response":" Mar","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:11.474101846Z","response":"iner","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:11.790493903Z","response":"is","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:12.106910183Z","response":".","done":false} {"model":"phi3:mini","created_at":"2024-07-21T05:44:12.423664722Z","response":"","done":true,"done_reason":"stop","context":[32010,751,1808,707,425,439,25054,5000,3814,12973,868,21423,899,5218,1577,32007,32001,997,439,25054,5000,3814,12973,868,21423,899,5218,29892,427,760,424,316,301,29915,1062,14508,634,427,409,12468,307,13775,316,425,5061,276,29892,707,16852,29889,6340,263,4370,27257,15826,610,966,6033,2708,270,30010,19908,6267,762,29884,316,425,12573,634,454,2245,25677,1671,16852,6303,8648,13704,712,8556,3667,14125,22572,29915,15669,427,16464,4191,19154,376,29924,1503,1642,10793,3814,12973,16053,479,22847,553,15087,1144,696,1173,1314,1027,309,7147,3479,286,7342,272,3246,24889,2406,1190,5061,276,29892,2257,1750,2424,1908,439,29915,1808,263,2653,7848,4760,1318,610,868,6316,1314,9122,28147,361,29889,5701,7101,707,1559,16027,15826,610,316,22114,1700,29883,550,634,553,22044,2406,427,13618,270,30010,279,2395,3805,29878,2445,352,4285,29892,16794,743,376,305,11625,532,613,8288,712,610,966,2298,13830,12286,696,1173,6394,11009,1041,1465,454,21423,899,5218,584,966,508,29891,787,6167,375,341,787,634,19918,267,1085,4983,275,29889],"total_duration":58835102724,"load_duration":15453689,"prompt_eval_count":17,"prompt_eval_duration":3436055000,"eval_count":190,"eval_duration":55339199000}
Intentaré algunas plantillas extra, pero el tamaño de mi tarjeta SD es limitado, voy a la borrar prelable el modelo Phi-3.
cpb@raspberrypi:~ $ ollama rm phi3:mini deleted 'phi3:mini'
Gema es una serie de modelos ofrecidos por Google Deepmind cuyo tamaño está optimizado. Hay una versión mínima con 2 mil millones de parámetros. Probaré la versión 1.1 de Gema:
cpb@raspberrypi:~ $ ollama pull gemma:2b pulling manifest pulling c1864a5eb193... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 1.7 GB pulling 097a36493f71... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 8.4 KB pulling 109037bec39c... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 136 B pulling 22a838ceb7fb... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 84 B pulling 887433b89a90... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 483 B verifying sha256 digest writing manifest removing any unused layers success
Este modelo es mucho más conciso en sus respuestas. Le hice la misma pregunta varias veces, sus respuestas en francés son menos buenas que en inglés (eso es normal, supongo que la muestra de entrenamiento es esencialmente de habla inglesa). Cabe señalar que en mi primera pregunta se tomó "know" en el sentido de "venir personalmente".
cpb@raspberrypi:~ $ ollama run gemma:2b >>> Connais-tu Obi-Wan Kenobi ? Je n'ai pas accès à la mémoire ou à l'apprentissage personnel, donc je n'ai pas connaissance de Obi-Wan Kenobi. >>> Qui est Obi-Wan Kenobi ? Obi-Wan Kenobi est un personnage fictif apparaissant dans la série de romans et de films "Star Wars". Il est un Jedi maître, un sage qui a été originaire sur la planète Terre. >>> /bye cpb@raspberrypi:~ $ ollama run gemma:2b >>> Qui est Obi-Wan Kenobi ? Obi-Wan Kenobi est un personnage fictif qui joue un rôle central dans la série de romans de science-fiction et de film de Disney "Star Wars". Il est le maître des Jedi, un ordre monastique qui sauve le monde de la malédiction du Sith >>> /bye cpb@raspberrypi:~ $ ollama run gemma:2b >>> Do you know Obi-Wan Kenobi? I do not have personal knowledge or the ability to form opinions. I am a large language model, trained by Google. >>> cpb@raspberrypi:~ $ ollama run gemma:2b >>> Do you know who Obi-Wan Kenobi is? Sure. Obi-Wan Kenobi is a fictional character in the Star Wars franchise of films, a series of science fiction movies produced by Lucasfilm. He is a highly skilled and experienced Jedi Knight, one of the most powerful and respected warriors in the galaxy. >>> Send a message (/? for help)
El modelo de parámetro de la versión Mistral de 0,3% a 7.000 millones de los que ofrece la startup francesa Mistral AIcon licencia Apache. La instalo:
cpb@raspberrypi:~ $ ollama pull mistral:7b pulling manifest pulling ff82381e2bea... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 4.1 GB pulling 43070e2d4e53... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 11 KB pulling 491dfa501e59... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 801 B pulling ed11eda7790d... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 30 B pulling 42347cd80dc8... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 485 B verifying sha256 digest writing manifest removing any unused layers success cpb@raspberrypi:~ $
Intenté algo que resultó ser bastante gracioso, le di las primeras palabras del bazo de Beaudelaire pidiéndole que completara la cita:
cpb@raspberrypi:~ $ ollama run mistral:7b >>> Continue cette citation "Quand le ciel bas et lourd pèse comme un couvercle" Ou peut-être que c'est l'âme qui plaint sous la pression de ses pensées, Et que les nuages gris se sont accumulés en réponse à nos désespoirs. Les murs se contractent sous le poids d'un regard triste et déchiré, Et chaque voix qui s'élève vers le ciel semble retentir dans une chambre vide. <no value> Ou peut-être que la nuit s'est abstraite pour nous laisser seul avec nos pensées, Pour que nous puissions nous regarder dans le miroir de nos vies et trouver des réponses, Et que chaque étoile qui brillait à travers les nuages est une question à laquelle nous avons répondu.
Incluso si la respuesta no es en absoluto el texto del poema original, encuentro que el estado de ánimo está muy cerca de él, y que en general el texto generado tiene buenas cualidades poéticas. También se señalará que <no value>
que, supongo, señala una línea vacía para cantar atrofa aquí.
Lo intenté de nuevo en inglés con el comienzo de Kipling de "If", sin embargo los resultados son mucho menos poéticos. Tal vez un sesgo debido a la consulta de demasiados textos de desarrollo personal:
>>> Please complete this text: "If you can keep your head when all about you are losing theirs and" remain calm, and in control. That is the sign of a true leader. In other words, it means that even in chaotic or stressful situations, you should be able to think clearly and make rational decisions. This quality is often sought after in leadership roles because it shows that you can maintain composure, focus on the task at hand, and not let emotions cloud your judgment. Being able to keep your head when everyone around you is losing theirs can also help build trust among your team or colleagues. They will see that they can rely on you to stay calm and steady in difficult situations, which can help improve morale and increase productivity. Overall, keeping your head in stressful situations is an essential skill for anyone who wants to succeed in their personal or professional life. It requires discipline, self-awareness, and the ability to stay focused on the task at hand. But by cultivating this skill, you can become a more effective leader, build stronger relationships, and achieve greater success.
La familia modelo Llama distribuida por Meta bajo licencia "Política de Uso Aceptable de Llama" está disponible en varias generaciones. El más poderoso es Llama3, pero creo que es demasiado grande para el recuerdo de la pequeña Raspberry Pi. Por otro lado, la versión 2 está disponible en un modelo de parámetro de 7.000 millones que voy a tratar de usar.
cpb@raspberrypi:~ $ ollama pull llama2:7b pulling manifest pulling 8934d96d3f08... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 3.8 GB pulling 8c17c2ebb0ea... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 7.0 KB pulling 7c23fb36d801... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 4.8 KB pulling 2e0493f67d0c... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 59 B pulling fa304d675061... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 91 B pulling 42ba7f8a01dd... 100% ▕█████████████████████████████████████████████████████████████████████████████████████▏ 557 B verifying sha256 digest writing manifest removing any unused layers success cpb@raspberrypi:~ $
La instalación del modelo está bien, desafortunadamente su carga en la memoria es imposible:
cpb@raspberrypi:~ $ ollama run llama2:7b Error: model requires more system memory (8.4 GiB) than is available (7.6 GiB)
El objetivo de este experimento era ver si era posible utilizar un modelo de lenguaje LLM en un sistema relativamente pequeño como en el campo de los sistemas integrados. Por supuesto, no se trataba de entrenar el modelo que requiere enormes recursos computacionales en comparación con un Raspberry Pi.
Los resultados son sorprendentemente buenos. Algunos modelos de tamaños reducidos dan muy buenas respuestas. Estaba muy seducido por este pequeño experimento, probablemente lo voy a extender a otros sistemas incrustadostratando de deshacerse del sistema operativo tanto como sea posible.
Durante muchos ensayos, el Raspberry Pi fue desconectado de la red para asegurarse de que no hubiera interacciones con un servidor remoto.
He escuchado muchas críticas de IA por su consumo de energía. Sin embargo, vemos que entrevistar un pequeño LLM consumirá sólo 27W (la dieta del Raspberry Pi 5) durante unas decenas de segundos. El uso de un modelo es, por tanto, muy razonable. Por supuesto, la fase inicial de aprendizaje es mucho más cara, especialmente porque los LLM grandes de hoy en día son más de cientos de miles de millones de parámetros. Pero en comparación con el campo de las criptomonedas, o NFTs, no estoy seguro de que la IA sea la más vorac de energía.