{"id":381,"date":"2024-10-15T10:05:54","date_gmt":"2024-10-15T10:05:54","guid":{"rendered":"https:\/\/blog.uclm.es\/felixvillanueva\/?p=381"},"modified":"2024-10-15T10:05:54","modified_gmt":"2024-10-15T10:05:54","slug":"llm-101-introduccion","status":"publish","type":"post","link":"https:\/\/blog.uclm.es\/felixvillanueva\/2024\/10\/15\/llm-101-introduccion\/","title":{"rendered":"LLM 101 Introducci\u00f3n"},"content":{"rendered":"\n<p>Vamos a hacer una serie de preguntas r\u00e1pidas para ayudar a los alumnos a empezar a trabajar con modelos grandes del lenguaje o LLM (Large Language Model)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfQue es un modelo grande del lenguaje o LLM del ingl\u00e9s Large Language Model?<\/h2>\n\n\n\n<p>Es una red neuronal profunda (con muchas capas) dise\u00f1adas para procesar lenguaje natural (NLP del ingl\u00e9s <em>natural language processing<\/em>). Esto es, entender y generar lenguaje natural escrito. Como todas las redes neuronales, hay que entrenarlas. Una LLM se entrena con mucho texto y \u00abaprende\u00bb patrones complejos del lenguaje.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 se han puesto de moda?<\/h2>\n\n\n\n<p>Hace unos a\u00f1os, unas arquitecturas llamadas <a href=\"https:\/\/en.wikipedia.org\/wiki\/Transformer_(deep_learning_architecture)\">Transformer<\/a> y sobre todo, el entrenamiento masivo con toda la informaci\u00f3n que hay disponible en Internet ha hecho que los LLM tengan unas prestaciones incre\u00edbles en tareas concretas, mas all\u00e1 de las que originalmente fueron dise\u00f1adas. chatGPT (Generative Pre-trained Transformer) de OpenAI y BERT (Bidrectional Encoder Representations form Transformer) de google son las arquitecturas mas famosas. Una descripci\u00f3n de la arquitectura transformer puedes verla <a href=\"https:\/\/machinelearningmastery.com\/the-transformer-model\/\">aqu\u00ed<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfPero un LLM es un programa que ejecuto en mi ordenador?<\/h2>\n\n\n\n<p>No exactamente, es un archivo binario que contiene la configuraci\u00f3n de la red neuronal despu\u00e9s del entrenamiento, esto es, los \u00abpesos\u00bb de cada neurona, de cada capa, calculados en el proceso de aprendizaje.<br>Los modelos pueden tener distintos formatos, generalmente indicados en el nombre. Aunque no hay un est\u00e1ndar de nombrado, se detectan patrones en el nombrado de los modelos. Por ejemplo, <a href=\"https:\/\/huggingface.co\/TheBloke\/SynthIA-7B-v2.0-16k-AWQ\">SynthIA-7B-v2.0-16k-AWQ<\/a> es un modelo entrenado con 7B, siete billones de par\u00e1metros, en su versi\u00f3n 2.0 y con un tama\u00f1o de contexto de 16K. La AWQ indica el formato y la precisi\u00f3n en el cual se han almacenado los \u00abpesos\u00bb de cada neurona.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 es el tama\u00f1o del contexto?<\/h2>\n\n\n\n<p>Una cosa es el modelo LLM y otra cosa son sus par\u00e1metros. El tama\u00f1o del contexto es el n\u00famero m\u00e1ximo de tokens (palabras) que le puedes pasar al LLM. Lo define la arquitectura del LLM y generalmente, a mayor tama\u00f1o del contexto, mejor se puede especificar la tarea que le pides al LLM por lo que generar\u00e1 cosas mas precisas. Tambi\u00e9n es cierto que generalmente, implica mas memoria. Es el <em>prompt<\/em> que le metes a chatGPT para que te responda.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vale, pero \u00bfC\u00f3mo ejecuto un LLM en mi m\u00e1quina?<\/h2>\n\n\n\n<p>Bien, tienes que cargar el modelo binario en memoria para poder introducirles contexto (el famoso prompt) y obtener lo que genera. Los modelos pueden ser muy grandes por lo que los requisitos hardware son exigentes. Dicho esto, hay librer\u00edas en varios lenguajes de programaci\u00f3n que te permiten cargar en memoria e interactuar con LLMs mediante un sencillo programa.<br>Uno de los mejores recursos para trabajar en este campo y en IA en general es la web https:\/huggingface.co , que tiene librer\u00edas, modelos, datasets, papers, etc. <a href=\"https:\/\/huggingface.co\/docs\/hub\/index\">la gu\u00eda de uso de esta p\u00e1gina<\/a> es un buen primer comienzo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfMe puedes poner un ejemplo?<\/h2>\n\n\n\n<p>El c\u00f3digo python de mas abajo carga un modelo un modelo LLM de c\u00f3digo abierto modesto, que se baja de la web https:\/\/huggingface.co\/ e interacciona con \u00e9l introduci\u00e9ndoles prompts (el contexto que habl\u00e1bamos antes) y obteniendo las respuestas. Realmente trata de predecir la siguiente palabra al prompt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import time\nimport torch\nimport transformers\nimport accelerate\n\nfrom transformers import AutoTokenizer, AutoModelForCausalLM\n\nprint(\"Loading model...\")\nprint(\"transformer version: \", transformers.__version__)\nprint(\"accelerate version: \", accelerate.__version__)\ntimeStart = time.time()\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"Using device:\", device)\n\nhugginfacemodelname = \"openchat\/openchat-3.5-1210\"\ntokenizer = AutoTokenizer.from_pretrained(hugginfacemodelname)\nmodel = AutoModelForCausalLM.from_pretrained(\n    hugginfacemodelname,\n    torch_dtype=torch.bfloat16,\n    low_cpu_mem_usage=True,\n).to(device)\n\nprint(\"Load model time: \", -timeStart + time.time())\n\nwhile True:\n    input_str = input(\"Enter: \")\n    input_token_length = input(\"Enter length: \")\n    if input_str == \"exit\":\n        break\n    timeStart = time.time()\n    inputs = tokenizer.encode(input_str, return_tensors=\"pt\").to(device)\n    outputs = model.generate(\n        inputs,\n        max_new_tokens=int(input_token_length),\n    )\n    output_str = tokenizer.decode(outputs&#091;0])\n    print(output_str)\n    print(\"Time taken: \", -timeStart + time.time())<\/code><\/pre>\n\n\n\n<p>El c\u00f3digo utiliza la librer\u00eda python transformers y torch. En primer lugar se indica el modelo LLM a cargar, openchat\/openchat-3.5-1210 y se genera el <em>tokenizer<\/em> que no es sino una herramienta que convierte el texto en tokens (palabras). Para el modelo que hemos especificado, la funci\u00f3n \u00abfrom_pretained\u00bb busca y carga el tokenizador correspondiente. Si se lo tiene que bajar, esto puede tardar. A continuaci\u00f3n, con AutoModelForCausalLM.from_pretained.., se carga el modelo de lenguaje causal, un tipo de modelo que predice la siguiente palabra en una secuencia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfHay mas tipos de modelos?<\/h2>\n\n\n\n<p>Si, en esa librer\u00eda hay modelos espec\u00edficos para <a href=\"https:\/\/huggingface.co\/docs\/transformers\/v4.40.2\/en\/model_doc\/auto#transformers.AutoModelForQuestionAnswering\">pregunta-respuesta<\/a>, para <a href=\"https:\/\/huggingface.co\/docs\/transformers\/v4.40.2\/en\/model_doc\/auto#transformers.AutoModelForImageClassification\">clasificaci\u00f3n de im\u00e1genes<\/a>, <a href=\"https:\/\/huggingface.co\/docs\/transformers\/v4.40.2\/en\/model_doc\/auto#multimodal\">multimodales<\/a>, etc. al cual le tienes que indicar qu\u00e9 modelo quieres entrenar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfEl prompt o la entrada del LLM c\u00f3mo se articula?<\/h2>\n\n\n\n<p>Asociado al concepto de LLM aparece el concepto de <em>prompt engineering<\/em> o ingenier\u00eda de prompts. Es importante destacar que un buen <em>prompt<\/em> o cadena de <em>prompts<\/em> puede mejorar mucho la salida de una determinada LLM en una tarea espec\u00edfica. En los \u00faltimos a\u00f1os aparece una gran cantidad de m\u00e9todos para elaborar prompts:<br>Referencias: https:\/\/dl.acm.org\/doi\/pdf\/10.1145\/3560815<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bf Puedo entrenar un LLM en lo que yo quiera?<\/h2>\n\n\n\n<p>En principio si. Entrenar un LLM desde cero requiere de muchos recursos. La mayor\u00eda de los ingenieros hacen un proceso denominado <em>finetunning<\/em> que no es otra cosa que coger un modelo LLM ya entrado de forma gen\u00e9rica y aplicarles un proceso de entrenamiento con un conjunto de datos espec\u00edfico de la tarea donde quiero usar mi LLM. El resultado es un modelo LLM que tiene el conocimiento general y se ha especializado mediante lo que ha aprendido con los patrones del <em>dataset<\/em> con el cual has hecho el <em>finetunning<\/em>. Un ejemplo muy bueno que aparece en los v\u00eddeos de formaci\u00f3n de google relacionados con LLM, es ver el <em>finetunning<\/em> similar al proceso de ense\u00f1arle a una mascota, por ejemplo un perro, una serie de tareas espec\u00edficas (buscar droga, personas, \u00f3rdenes, etc.). Tienes el perro, siendo en este simil, la LLM generalista, y mediante un proceso de entrenamiento (<em>finetunning<\/em>), obtienes una LLM que es mejor que la generalista en un proceso espec\u00edfico.<\/p>\n\n\n\n<p>Otra t\u00e9cnica muy adecuada es el Retrieval Augmented Generation o RAG, que no es sino mejorar las respuestas de LLM en un dominio espec\u00edfico proporcion\u00e1ndole informaci\u00f3n espec\u00edfica de ese dominio. Lo que se hace es recuperar informaci\u00f3n relevante (de fuentes internas o externas) para la pregunta e introducirla en el contexto\/prompt junto con la pregunta para obtener mejores respuestas. Realmente todo este proceso de recuperaci\u00f3n lo que hace es mejorar el prompt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Finetunning<\/em><\/h2>\n\n\n\n<p>En <a href=\"https:\/\/towardsdatascience.com\/fine-tuning-large-language-models-llms-23473d763b91\">este enlace<\/a> podemos ver los principios b\u00e1sicos de finetunning:<br>hay tres aproximaciones al finetuning<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Self-supervised learning<\/li>\n\n\n\n<li>Supervised learning<\/li>\n\n\n\n<li>Reinforcement learning<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><em>\u00bfPor qu\u00e9 ocupa tanto una LLM?<\/em><\/h2>\n\n\n\n<p>Una red neuronal almacena pesos calculados en el proceso de entrenamiento, como toda<br>variable, esos pesos pueden almacenarse en diverso formatos (punto flotante vs entero) y con determinada precisi\u00f3n (64,32,16 bits). La precisi\u00f3n es importante por que es lo que almacena los patrones aprendidos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>\u00bfQu\u00e9 puedo hacer para reducir el tama\u00f1o de una LLM?<\/em><\/h2>\n\n\n\n<p>Hay un proceso, denominado cuantizaci\u00f3n, que pasa de una determinada precisi\u00f3n a otra. Si pasas de una precisi\u00f3n en punto flotante de 16 bits a un entero de 8 bits, esto hace que el modelo ocupe menos en el disco duro a costa de perder informaci\u00f3n\/patrones. Es decir, el modelo es algo peor. Hay dos tipos de cuantizaci\u00f3n, sim\u00e9trica y asim\u00e9trica Mas info: <a href=\"https:\/\/myscale.com\/blog\/es\/quantization-for-llms-finetuning\/\">https:\/\/myscale.com\/blog\/es\/quantization-for-llms-finetuning\/<\/a><\/p>\n\n\n\n<p>En el siguiente ejemplo podemos ver un ejemplo b\u00e1sico de finetunning para evaluar sentimiento en comentarios de pel\u00edculas. El ejemplo es muy sencillo pero completo, en primer lugar se eval\u00faa con un peque\u00f1o testbench la LLM escogida, una de las mas sencillas, se entrena con un dataset de comentarios etiquetados y se vuelve a evaluar para ver si ha \u00abaprendido\u00bb. <a href=\"https:\/\/towardsdatascience.com\/fine-tuning-large-language-models-llms-23473d763b91\">https:\/\/towardsdatascience.com\/fine-tuning-large-language-models-llms-23473d763b91<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfC\u00f3mo evaluamos un LLM?<\/h2>\n\n\n\n<p>C\u00f3mo sabemos si una LLM es buena o malo y qu\u00e9 podemos probar para ver si hemos mejorado. Bueno, aqu\u00ed entra en juego la evaluaci\u00f3n de las redes neuronales en general. Es decir, evaluar las prestaciones en base a una tarea espec\u00edfica pasa inherentemente por poder evaluar c\u00f3mo de bueno son los resultados obtenidos ante <em>prompts<\/em> especificos.<\/p>\n\n\n\n<p>Dos paradigmas populares, para la evaluaci\u00f3n gen\u00e9rica de LLMs:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>El tradicional NLP Benchmark approach usando, por ejemplo, MosaicML&#8217;s Eval Gauntlet.<\/li>\n\n\n\n<li>Otra t\u00e9cnica muy utilizada es , precisamente, utilizar una LLM como juez.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 LLM es mejor?<\/h2>\n\n\n\n<p>Con la aparici\u00f3n de m\u00faltiples LLMs han aparecido numerosas m\u00e9tricas y <em>rankings<\/em> en diferentes <em>testbench<\/em>. Aqu\u00ed puedes ver el ranking de <em>hugging face<\/em>: <a href=\"https:\/\/huggingface.co\/spaces\/HuggingFaceH4\/open_llm_leaderboard\">link<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Herramientas y recursos<\/h2>\n\n\n\n<p><a href=\"https:\/\/pinokio.computer\">https:\/\/pinokio.computer<\/a>\/ una WEBUI para instalar y lidiar con modelos de AI.<br><a href=\"https:\/\/huggingface.co\/TheBloke\">https:\/\/huggingface.co\/TheBloke<\/a> Distintos modelos y par\u00e1metros para poder ser ejecutados en m\u00e1quinas mas modestas<br><a href=\"https:\/\/github.com\/jmorganca\/ollama\">https:\/\/github.com\/jmorganca\/ollama<\/a> herramienta para ejecutar LLM de forma local y hacerle un <em>wrapper<\/em> python que te permita adaptar los prompts\/salidas.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Terminolog\u00eda:<\/h1>\n\n\n\n<p>&#8211;<em>Cuantizaci\u00f3n<\/em>: Reduce la precisi\u00f3n de los n\u00fameros utilizados para representar los pesos en el modelo, pierdes precisi\u00f3n pero el tama\u00f1o y la inferencia se acelera sin necesitar tantos recursos.<br>&#8211;<em>GPTQ<\/em> : formato de cuantizaci\u00f3n<br>-AWQ : formato de cuantizaci\u00f3n<br>-GGUF : formato de modelos que reemplaza a GGML.<br>&#8211;<em>Tama\u00f1o del contexto<\/em>: la cantidad de tokens (normalmente palabras ) que un modelo puede considerar en un prompt de una vez cuando genera una respuesta o predicci\u00f3n.<br>Formatos de los modelos <a href=\"https:\/\/book.premai.io\/state-of-open-source-ai\/model-formats\/\">models in open AI book<\/a><br>&#8211; Destilaci\u00f3n (Distillation)  es el proceso de entrenar un modelo peque\u00f1o (llamado estudiante) para emular las respuestas de un modelo mas grande (profesor).<br>-Pruning es el proceso de elminar las salidas no cr\u00edticas del modelo peque\u00f1o o estudiante.<br>-Quantization es el proceso de reducir la precisi\u00f3n de los pesos del modelo y las activaciones.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bibliograf\u00eda<\/h2>\n\n\n\n<p><a href=\"https:\/\/book.premai.io\/state-of-open-source-ai\/\">Open source LLM<\/a><br><a href=\"https:\/\/synthical.com\/article\/91ef24f2-433f-4e02-a989-67f8ae8b69b1\">XGen-7B Technical Report<\/a> un LLM open source con un prompt de hasta 8K<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vamos a hacer una serie de preguntas r\u00e1pidas para ayudar a los alumnos a empezar a trabajar con modelos grandes del lenguaje o LLM (Large Language Model) \u00bfQue es un modelo grande del lenguaje o LLM del ingl\u00e9s Large Language &hellip; <a href=\"https:\/\/blog.uclm.es\/felixvillanueva\/2024\/10\/15\/llm-101-introduccion\/\">Sigue leyendo <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":182,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,48,6],"tags":[21,26,49,43],"class_list":["post-381","post","type-post","status-publish","format-standard","hentry","category-ejemplos","category-llm","category-tutorial","tag-ejemplos","tag-iot","tag-llm","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/381","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/users\/182"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/comments?post=381"}],"version-history":[{"count":4,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/381\/revisions"}],"predecessor-version":[{"id":385,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/381\/revisions\/385"}],"wp:attachment":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/media?parent=381"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/categories?post=381"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/tags?post=381"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}