{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "28b3bac4", "metadata": {}, "source": [ "
\n", " \n", "
\n", "\n", "# Aprendizaje Profundo" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d56e0058", "metadata": {}, "source": [ "#
Diplomado en Inteligencia Artificial y Aprendizaje Profundo
" ] }, { "attachments": {}, "cell_type": "markdown", "id": "861198e0-35ab-4ec6-87a9-094fdcdcb444", "metadata": {}, "source": [ "#
Modelos Generativos
" ] }, { "attachments": {}, "cell_type": "markdown", "id": "7eb54ad0-54cc-46cf-8d4e-c5b04a8c2a3f", "metadata": { "tags": [] }, "source": [ "
GPT, GPT-2, GPT-3, Megatron, Turing-NLG, Blenderbot, Blenderbot2, OPT
" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4e8e7da2", "metadata": {}, "source": [ "## Profesores" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f93421c0", "metadata": {}, "source": [ "1. Alvaro Montenegro, PhD, ammontenegrod@unal.edu.co\n", "1. Camilo José Torres Jiménez, Msc, cjtorresj@unal.edu.co\n", "1. Daniel Montenegro, Msc, dextronomo@gmail.com " ] }, { "attachments": {}, "cell_type": "markdown", "id": "fced1bbf", "metadata": {}, "source": [ "## Asesora Medios y Marketing digital" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bd2d7262", "metadata": {}, "source": [ "4. Maria del Pilar Montenegro, pmontenegro88@gmail.com\n", "5. Jessica López Mejía, jelopezme@unal.edu.co\n", "6. Venus Puertas, vpuertasg@unal.edu.co" ] }, { "attachments": {}, "cell_type": "markdown", "id": "23936fae", "metadata": {}, "source": [ "## Jefe Jurídica" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b67f06d0", "metadata": {}, "source": [ "7. Paula Andrea Guzmán, guzmancruz.paula@gmail.com" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b5602baf", "metadata": {}, "source": [ "## Coordinador Jurídico" ] }, { "attachments": {}, "cell_type": "markdown", "id": "cdf33154", "metadata": {}, "source": [ "8. David Fuentes, fuentesd065@gmail.com" ] }, { "attachments": {}, "cell_type": "markdown", "id": "5586caa6", "metadata": {}, "source": [ "## Desarrolladores Principales" ] }, { "attachments": {}, "cell_type": "markdown", "id": "fde2197b", "metadata": {}, "source": [ "9. Dairo Moreno, damoralesj@unal.edu.co\n", "10. Joan Castro, jocastroc@unal.edu.co\n", "11. Bryan Riveros, briveros@unal.edu.co\n", "12. Rosmer Vargas, rovargasc@unal.edu.co" ] }, { "attachments": {}, "cell_type": "markdown", "id": "558ef66a", "metadata": {}, "source": [ "## Expertos en Bases de Datos" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f1c447d6", "metadata": {}, "source": [ "13. Giovvani Barrera, udgiovanni@gmail.com\n", "14. Camilo Chitivo, cchitivo@unal.edu.co" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ef0a1a0b-6b3a-4c06-ba2f-52c4410927dc", "metadata": { "slideshow": { "slide_type": "subslide" }, "tags": [] }, "source": [ "## Referencias" ] }, { "attachments": {}, "cell_type": "markdown", "id": "a4119ccb-1bd9-436e-a189-ad1424fddf96", "metadata": {}, "source": [ "1. [Improving Language Understanding\n", "by Generative Pre-Training](https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf), Radford A. et al., 2018\n", "1. [Language Models are Unsupervised Multitask Learners](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf), Radford A. et al., 2019\n", "1. [Language Models are Few-Shot Learners](https://arxiv.org/pdf/2005.14165.pdf), Brown T. et al., Julio de 2020\n", "1. [Turing-NLG: A 17-billion-parameter language model by Microsoft](https://www.microsoft.com/en-us/research/blog/turing-nlg-a-17-billion-parameter-language-model-by-microsoft/), Febrero 13 de 2020\n", "1. [Recipes for building an open-domain chatbot](https://arxiv.org/pdf/2004.13637.pdf), Roller S. et al., Abril 28 de 2020\n", "1. [Internet-Augmented Dialogue Generation](https://arxiv.org/pdf/2107.07566.pdf), Komeili M. et al., 15 de Julio de 2021\n", "1. [Beyond Goldfish Memory: Long-Term Open-Domain Conversation](https://arxiv.org/pdf/2107.07567.pdf), Xu J. et al., 15 de Julio de 2021\n", "1. [Using DeepSpeed and Megatron to Train Megatron-Turing NLG 530B, A Large-Scale Generative Language Model](https://arxiv.org/pdf/2201.11990.pdf), 4 de Febrero de 2022\n", "1. [PaLM: Scaling Language Modeling with Pathways](https://arxiv.org/pdf/2204.02311.pdf), 5 de Abril de 2022\n", "1. [OPT: Open Pre-trained Transformer Language Models](https://arxiv.org/pdf/2205.01068.pdf), 5 de Mayo de 2022\n", "1. [Aprendizaje Profundo-Diplomado](https://github.com/AprendizajeProfundo/Diplomado)\n", "1. [Aprendizaje Profundo-PLN](https://github.com/AprendizajeProfundo/PLN)\n", "1. [Ashish Vaswani et al., Attention Is All You Need](https://arxiv.org/pdf/1706.03762.pdf), diciembre 2017.\n", "1. [Dennis Rothman, Transformers for Natural Language processing](http://libgen.rs/search.php?req=Transformers+for+Natural+Language+processing&open=0&res=25&view=simple&phrase=1&column=def), enero 2021.\n", "1.[ Varios, Dive into deep learning](https://d2l.ai/), enero 2021" ] }, { "attachments": {}, "cell_type": "markdown", "id": "6e6851c8-1883-4221-af4d-ff7c6cdda878", "metadata": { "slideshow": { "slide_type": "subslide" }, "tags": [] }, "source": [ "## Contenido" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2e850d72-3017-4eb8-9ff2-a153114e674e", "metadata": { "origin_pos": 0 }, "source": [ "* [Introducción](#)\n", "* [GPT](#GPT)\n", "* [GPT-2](#GPT-2)\n", "* [Megatron y Turing-NLG](#Megatron-y-Turing-NLG)\n", "* [GPT-3](#GPT-3)\n", "* [BlenderBot](#BlenderBot)\n", "* [BlenderBot2](#BlenderBot2)\n", "* [OPT](#OPT)\n", "* [PaLM](#PaLM)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "12142d59-234d-45ee-870a-73f16e123fce", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## Introducción" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ed23d817-3335-4e3e-962f-e37f6ebfdae5", "metadata": {}, "source": [ "Para esta lección final en lenguaje natural, veamos un mapa cronológico de los modelos Transformers:\n", "\n", "![t-crono](../Imagenes/transformers_chrono.svg)\n", "Fuente: [How do Transformers work?](https://huggingface.co/course/chapter1/4?fw=pt#how-do-transformers-work)\n", "\n", "Como se puede observar, hay muchos modelos que aún falta revisar.\n", "\n", "Sin embargo, el grueso de las metodologías está completo.\n", "\n", "Un hecho bastante impactante, es la aparente moda, como se ve a continuación:\n", "\n", "![t-big](../Imagenes/models_HF.png)\n", "Fuente: [Transformers are big models](https://huggingface.co/course/chapter1/4?fw=pt#transformers-are-big-models)\n", "\n", "Aunque esto pareciera estadísticamente incorrecto y hasta matemáticamente tramposo, hay una razón de fondo para esta tendencia, que veremos más adelante y que justifica tal moda que parece no tener un límite cercano.\n", "\n", "![t-big-2022](../Imagenes/models_2022.jpeg)\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d52a4a86-18ef-40a6-93de-3fe56854b635", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bcd0e15d-0b4a-4234-af2b-ae994161a22b", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## GPT" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2794aa55-ebdf-44e1-ac2a-db448c8fd678", "metadata": {}, "source": [ "GPT significa **G**enerative **P**re-trained **T**ransformer, y fue un modelo construido por el equipo de OpenAI de esa época para demostrar las capacidades de los modelos transformers.\n", "\n", "Fue hecho a la par con el modelo BERT, pero en este caso, sólo se tomó la parte decodificadora del transformer original.\n", "\n", "Recordemos la arquitectura del transformer original:\n", "\n", "![trans](../Imagenes/Transformer_original.png)\n", "\n", "En comparación con la arquitectura BERT, como el decodificador es un modelo auto-regresivo, no permite mirar tokens hacia adelante cuando se intenta generar texto.\n", "\n", "Entonces, la estrategia de entrenamiento es sencilla: Entrenar el modelo en un corpus no etiquetado y hacer un fine-tuning de **cambios mínimos de la arquitectura** para tareas específicas y ver su comportamiento en las tareas de NLU, por ejemplo, mirando el GLUE y otros.\n", "\n", "Recordemos que la justificación de esta técnica es el hecho de no tener acceso a datasets etiquetados de gran magnitud, porque son costosos y de tiempo extenso de construcción. Incluso en el caso de tenerlos, un gran problema es la calidad de los embeddings de los tokens.\n", "\n", "Por otro lado, en el paper se cuestiona la manera más eficiente de hacer transfer learning.\n", "\n", "Siguiendo una línea de pensamiento específica, OpenAI decide recurrir a funciones auxiliares para realizar este proceso de fine-tuning.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "632ca87f-b5a3-4cb0-ae0c-e293a2c2d5ee", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Pre-entrenamiento" ] }, { "attachments": {}, "cell_type": "markdown", "id": "6b416107-4b0d-4a0a-a04f-4dd9d1829d5d", "metadata": {}, "source": [ "Para esta primera fase, el modelo se entrena con la siguiente función de verosimilitud (maximización):\n", "\n", "$$L_1(U) = \\sum_i\\log P(u_i|u_{i-k},\\dots,u_{i-1};\\Theta)$$\n", "\n", "donde $U=\\{u_1,\\dots,u_n\\}$ es la tokenización del corpus no etiquetado, $k$ es la ventana de contexto, y $P$ es la probabilidad condicional, que es modelada con una red neuronal con parámetros $\\Theta$. Los parámetros se entrenan usando gradiente descendiente estocástico." ] }, { "attachments": {}, "cell_type": "markdown", "id": "09201716-5df3-44a6-bd3c-2c8b1de7b5b5", "metadata": {}, "source": [ "El modelo GPT es realmente, sencillo, como su ecuación indica:\n", "\n", "![gpt_eq](../Imagenes/gpt_eq.png)\n", "\n", "Fuente: [Improving Language Understanding\n", "by Generative Pre-Training](https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf)\n", "\n", "donde $U$ es el vector de contexto de los tokens, $n$ es el número de layers, $W_e$ la matriz de embeddings de los tokens y $W_p$ la matriz de embedding posicional.\n", "\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2ef6ca46-e772-47ba-b4b1-ddcba7b5aca9", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Fine-tuning" ] }, { "attachments": {}, "cell_type": "markdown", "id": "0ec84237-9a76-4181-8401-0424ee4010cb", "metadata": {}, "source": [ "Para el fine-tuning, se asume que se tiene una sucesión de tokens de entrada $x^1, \\dots, x^m$ con una etiqueta $y$ de algún conjunto etiquetado $C$.\n", "\n", "En este caso:\n", "\n", "$$P(y|x^1, \\dots, x^m)=\\text{softmax}(h_{l}^{m} W_y)$$\n", "\n", "Dando el siguiente objetivo a maximizar:\n", "\n", "$$L_2(C) = \\sum_{(x,y)}\\log P(y|x^1, \\dots, x^m)$$\n", "\n", "El equipo de OpenAI encontró que la siguiente función auxiliar ayuda a la generalización del modelo supervisado, junto con una aceleración en la convergencia del modelo:\n", "\n", "$$L_3(C) = L_2(C) + \\lambda*L_1(C)$$\n", "\n", "En conclusión, los únicos hiperparámetros extra en el finetuning son los de $W_y$ y loss embeddings para delimitar los tokens en las respuestas." ] }, { "attachments": {}, "cell_type": "markdown", "id": "e1a753f9-faaf-495c-917f-e58b4ae78db1", "metadata": {}, "source": [ "Una forma más ilustrativa de ver la metodología es la siguiente:\n", "\n", "![gpt_eq](../Imagenes/gpt_model.png)\n", "\n", "Fuente: [Improving Language Understanding\n", "by Generative Pre-Training](https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf)\n", "\n", "Mayores detalles de las estrategias supervisadas para las tareas evaluadas se encuentran en el paper." ] }, { "attachments": {}, "cell_type": "markdown", "id": "249dd638-b935-445a-a8f0-89db076b5226", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Datasets" ] }, { "attachments": {}, "cell_type": "markdown", "id": "52acc2db-1b63-41a1-841f-b73a5a0b638a", "metadata": {}, "source": [ "Este modelo fue entrenado utilizando el siguiente dataset:\n", "\n", "* BookCorpus (7.000 libros únicos sin publicar de una amplia gama de géneros, incluyendo Aventura, Fantasía y Romance)." ] }, { "attachments": {}, "cell_type": "markdown", "id": "ecd88c46-9d59-48d2-8103-5766d6204406", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Especificaciones del Modelo" ] }, { "attachments": {}, "cell_type": "markdown", "id": "a07a4e79-c066-44a0-9603-3485640f1e68", "metadata": {}, "source": [ "* 12 capas decodificadores de transformer.\n", "* 12 cabezas de atención.\n", "* 768 dimensiones del embedding.\n", "* Estados internos de 3072 en las capas FFN.\n", "* Optimizador Adam (max lr=2.5e-4).\n", " * lr fue incrementada desde cero las primeras 2000 actualizaciones y puesta a cero utilizando un scheduker de coseno.\n", "* Se entrenó 100 epochs con minibatches de 64, secuencias de 512 tokens.\n", "* Tokenización BPE. con vocabulario de 40.000 mergimientos.\n", "* Dropout de 0.1.\n", "* Función de activatión GELU (Gaussian Linear Unit).\n", "\n", "\n", "Para procesos de fine-tuning, se utilizan los mismos parámetros que el pre-training, excepto en la tasa de aprendizaje (lr=6.25e-5) con batches de 32, sólo por 3 epochs y $\\lambda=0.5$." ] }, { "attachments": {}, "cell_type": "markdown", "id": "d802ecea-9cd0-4076-8978-84b421ad8554", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Resultados" ] }, { "attachments": {}, "cell_type": "markdown", "id": "200bf052-4398-45aa-aec4-d741843a2b9c", "metadata": {}, "source": [ "![r1](../Imagenes/gpt_res_1.png)\n", "![r2](../Imagenes/gpt_res_2.png)\n", "![r3](../Imagenes/gpt_res_3.png)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d2adcf3c-639e-4ae6-abc0-64af8fdc9332", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Análisis" ] }, { "attachments": {}, "cell_type": "markdown", "id": "26c8c396-b539-4a4e-aea2-cbd96813733a", "metadata": {}, "source": [ "A continuación, podemos ver el número de capas de transformer transferidas a las tareas supervisadas.\n", "\n", "Como se puede observar, cada capa del transformer juega un papel fundamental para la tarea luego del pre-training.\n", "\n", "Esto quiere decir que estas capas contienen funcionalidades importantes sobre cada una de las tareas evaluadas." ] }, { "attachments": {}, "cell_type": "markdown", "id": "4ffaad15-28ba-4cc1-a4dc-74247361d9ab", "metadata": {}, "source": [ "![an](../Imagenes/gpt_an.png)\n", "\n", "Y finalmente, podemos ver un estudio de ablación:\n", "\n", "![ablation](../Imagenes/gpt_ablation.png)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "dff70915-1057-4586-bb61-4757b2d32a4d", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Modelo en Acción" ] }, { "cell_type": "code", "execution_count": 2, "id": "dc00ea0c-9eac-41f0-942e-34fd7f24d716", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Cargando GPT...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Some weights of OpenAIGPTLMHeadModel were not initialized from the model checkpoint at openai-gpt and are newly initialized: ['lm_head.weight']\n", "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Cargando Traductor Inglés-Español...\n", "Cargando Traductor Español-Inglés...\n", "Listo!!!\n" ] } ], "source": [ "from transformers import pipeline\n", "\n", "# Generador de Texto\n", "print('Cargando GPT...')\n", "gpt = pipeline(task='text-generation',model='openai-gpt')\n", "\n", "# Españolización Rápida\n", "print('Cargando Traductor Inglés-Español...')\n", "trad_en_es = pipeline(task='translation',model='Helsinki-NLP/opus-mt-en-es')\n", "print('Cargando Traductor Español-Inglés...')\n", "trad_es_en = pipeline(task='translation',model='Helsinki-NLP/opus-mt-es-en')\n", "print('Listo!!!')" ] }, { "cell_type": "code", "execution_count": 12, "id": "806d4462-6ef2-457e-8c86-b7fcca297851", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Holaa\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Hola. encontrarás a mi amiga ahí abajo con nosotros. ella está muy ocupada, y realmente no tengo el tiempo para encontrar a alguien, así que - ¿quieres reunirte con nosotros mientras conducimos? \" \" seguro, voy a recogerla. \" \" genial. vas a tener que aparcar a una cuadra de distancia porque todo el mundo ya está estacionando así - \" se detuvo y se volvió hacia nosotros. \" es esta una reunión de grupo? \" \" sí. \" asintió en Lucas. \" y vamos a mostrar a todos cómo lo hacemos. todo el mundo, este es Lucas, su jefe, y ese tipo grande de allí, ese tipo que vive en la casa con él.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " Estamos aprendiendo a hablar,\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Estamos aprendiendo a hablar, \"la mujer dijo después de otro par de minutos. \" ¿cómo se va a 'hablar?' hay un montón de palabras que no se nos permite utilizar, de todos modos. \" \"'usted está 'hablando' a algún tipo de máquina, \" la corrijo, \" así que todo lo que está recibiendo un poco es 'ir'no va '. \" miró hacia atrás, no estaba seguro de si quería ser serio o no. finalmente, puso sus manos detrás de su espalda y dijo, \" bueno, el problema es que no podemos hablar nosotros mismos. incluso con la ayuda de los'máquinas' somos capaces de tratar de hablarnos unos a otros. \" no estaba seguro de que me gustara el sonido de eso. no me gustó el sonido de nada de eso tampoco. y definitivamente no estaba seguro de que la máquina estaba ayudando a nadie. quiero decir, ¿quién eran ellos de todos modos?\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " [FIN]\n" ] } ], "source": [ "text=''\n", "\n", "import random\n", "while 1:\n", " text = str(input())\n", " \n", " if text=='[FIN]':\n", " break\n", " \n", " text_en = trad_es_en(text)[0]['translation_text']\n", " \n", " #ran_gen_len = random.randint(1,512)\n", " completion = gpt(text_en)[0]['generated_text']\n", " \n", " complet_es = trad_en_es(completion)[0]['translation_text']\n", " \n", " print(complet_es)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3599c1f1-e9a8-419e-ac1d-144791a89e6c", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Fine-Tuning" ] }, { "cell_type": "code", "execution_count": 21, "id": "0bb81fea-06b6-4adf-9cb7-8ec89ddb8592", "metadata": {}, "outputs": [], "source": [ "from transformers import AutoTokenizer, AutoModel\n", "\n", "gpt_tok = AutoTokenizer.from_pretrained('openai-gpt')\n", "gpt = AutoModel.from_pretrained('openai-gpt')" ] }, { "cell_type": "code", "execution_count": 35, "id": "99085863-a0ab-48c2-be18-4b16d9f34def", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'input_ids': tensor([[ 1329, 246, 240, 34998, 859, 557]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1]])}\n" ] }, { "data": { "text/plain": [ "torch.Size([1, 6, 768])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "text = 'Hola, cómo estás'\n", "tokens = gpt_tok(text, return_tensors='pt')\n", "out = gpt(input_ids=tokens['input_ids'],return_dict=False)\n", "\n", "print(tokens)\n", "out[0].shape\n", "\n", "### FINE-TUNING HERE ###" ] }, { "attachments": {}, "cell_type": "markdown", "id": "0555bbdc-b9e9-48bc-a951-d3c20dfc1bc8", "metadata": {}, "source": [ "**Reto:** Hacer Fine-tuning utilizando alguna técnica vista a lo largo de las lecciones para alguna tarea descrita en el paper." ] }, { "attachments": {}, "cell_type": "markdown", "id": "d4f1805c-c730-443b-8db1-0a0766d20239", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bdfa7814-6c3d-48ef-b01a-2aafb94f2425", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## GPT-2" ] }, { "attachments": {}, "cell_type": "markdown", "id": "9c6ea2e8-5193-4b04-a3ca-90eb203ac182", "metadata": {}, "source": [ "Luego del gran éxito de los modelos GPT y BERT, OpenAI no se cruzó de brazos y comenzó a entrenar el mismo modelo, pero con más parámetros y mayor número de capas de transformer.\n", "\n", "En esta ocasión, el modelo tiene 1500 millones de parámetros.\n", "\n", "Según Wikipedia,\n", "\n", "*\"Si bien se sabe que el costo de la capacitación de GPT-2 fue de 256 dólares por hora, se desconoce la cantidad de horas que tomó completar la capacitación; por lo tanto, el costo general de la capacitación no se puede estimar con precisión. Sin embargo, los costos de los modelos comparables de lenguaje grande que utilizan arquitecturas de transformer se han documentado con más detalle; los procesos de capacitación para BERT y XLNet consumieron, respectivamente, 6.912 y 245.000 dólares de recursos.\"*\n", "\n", "Podemos ir a la página oficial de OpenAI para leer el artículo [Better Language Models\n", "and Their Implications](https://openai.com/blog/better-language-models)." ] }, { "attachments": {}, "cell_type": "markdown", "id": "77da3b7d-e8de-4a82-a452-eda3621f3c19", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## Cambio de Paradigma: Ask The Model" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d1229b0c-214e-4a1e-a991-adaba1dd67cc", "metadata": {}, "source": [ "GPT-2 fue realmente una revolución en el mundo, y no sólo del Lenguaje Natural.\n", "\n", "Como se promete en el paper, \n", "\n", "*\"Las tareas de procesamiento del lenguaje natural, como la respuesta a preguntas, la traducción automática, la comprensión de lectura y los resúmenes, suelen ser abordadas con aprendizaje supervisado en conjuntos de datos específicos de tareas. Demostramos que los modelos de lenguaje comienzan a aprender estas tareas sin ninguna supervisión explícita cuando se entrenan en un nuevo conjunto de datos de millones de páginas web llamadas WebText.\"*\n", "\n", "WebText cuenta con aproximadamente 8 millones de texto, minados de Reddit, que no tienen problemas en la calidad de los datos, cómo sí lo tiene CommonCrawl. \n", "\n", "En tamaño, es aproximadamente 40G de puro texto.\n", "\n", "Para mayor detalle, podemos ir a [Reddit Science](https://www.reddit.com/r/science/) para un ejemplo de filtrado natural y entender cómo obtuvieron semejante cantidad de texto curado.\n", "\n", "A continuación, podemos observar una gráfica impactante:\n", "\n", "![gpt2zs](../Imagenes/gpt2_zs.png)\n", "\n", "A simple vista, parece un simple benchmark sobre una tarea de fine-tuning, pero en realidad, el modelo en sí está respondiendo a las tareas sin haber sido entrenado para tal tarea.\n", "\n", "En el mundo de la inteligencia artificial, esto se conoce como **Zero-Shot Learning**, la capacidad de un modelo para desempeñarse en tareas para las que no fue entrenado explícitamente, dejando quizás en próxima deprecación al fine-tuning.\n", "\n", "Este procedimiento se logra **\"hablando con el modelo\"**, o simplemente colocando todos los requerimientos en forma textual y esperar a la completación de texto que indique la respuesta a la pregunta indicada por el ente interactuando.\n", "\n", "Aunque en el paper se menciona que estos resultados no son del SOTA, **es realmente sorprendente que siquiera funcione.**\n", "\n", "A continuación, podemos observar los detalles de la arquitectura:\n", "\n", "![gpt_arch](../Imagenes/gpt_arch.png)\n", "\n", "Aunque en principio OpenAI escribió declaraciones sobre el potencial peligro de liberar su modelo más grande, el mercado los obligó a liberarlo, pues otras compañías ya lo habían hecho en el segundo semestre de 2019.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "1ea1f13b-6d34-4c57-ac1d-b3c21203f2a7", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Modificaciones del Modelo" ] }, { "attachments": {}, "cell_type": "markdown", "id": "83fa9baf-4890-497e-a3b3-71717a75c3dd", "metadata": {}, "source": [ "Las principales modificaciones respecto de su antecesor GPT, fueron las siguientes:\n", "\n", "* La capa de normalización fue movida al principio de cada sub-bloque, similar a una pre-activation en una red residual.\n", "* Una capa adicional de normalización fue puesta al final de cada bloque de atención.\n", "* Se hicieron modificaciones sobre la inicialización de los pesos para contar con las nuevas capas introducidas.\n", "* Se expandió el vocabulario a 50.257 tokens (usando tokenización BPE con modificaciones espaciales de mergimiento).\n", "* Se amplió el tamaño del contexto de 512 a 1024.\n", "* Se usaron batches de 512.\n", "\n", "Una observación importante es que todos los modelos aún no se ajustan a WebText y la perplejidad retenida hasta ahora puede mejorar con más tiempo de entrenamiento.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "7efa2f79-d909-477d-a619-b560da02bb39", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Resultados Zero-Shot" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e9734412-353b-4cb4-bb3a-d9b346247146", "metadata": {}, "source": [ "![gpt2_res_zs](../Imagenes/gpt2_res_zs.png)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "61305e64-f3f0-4f37-ba26-0731b1354331", "metadata": {}, "source": [ "Como ejemplo, expliquemos un poco el conjunto de datos **LAMBADA:**\n", "\n", "\n", "LAMBADA evalúa las capacidades de los modelos computacionales para la comprensión de textos mediante una tarea de predicción de palabras.\n", "\n", "LAMBADA es una colección de pasajes narrativos que comparten la característica de que los sujetos humanos pueden adivinar su última palabra si están expuestos al pasaje completo, pero no si solo ven la última oración que precede a la palabra objetivo.\n", "\n", "Para tener éxito en LAMBADA, los modelos computacionales no pueden basarse simplemente en el contexto local, sino que deben poder realizar un seguimiento de la información en el discurso más amplio." ] }, { "attachments": {}, "cell_type": "markdown", "id": "9dca20e0-16f5-4610-9a0f-b80b9f763c27", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Winograd Schema Challenge" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f1d540ec-2ed6-42a3-aa9a-b9623a90520f", "metadata": {}, "source": [ "El desafío del esquema de Winograd (Levesque et al., 2012) fue construido para medir la capacidad de un sistema para realizar un razonamiento de sentido común midiendo su capacidad\n", "para resolver ambigüedades en el texto. GPT-2 mejora la precisión del SOTA en un 7 %, alcanzando un 70,70 %\n", "\n", "![gpt_wsc](../Imagenes/gpt_wsc.png)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "801cd208-618d-4dbf-b243-5a020b3478a0", "metadata": {}, "source": [ "**Pregunta interesante: ¿Los modelos realmente están generalizando o simplemente memorizando?**\n", "\n", "Respuesta: Ir al paper, página 8." ] }, { "attachments": {}, "cell_type": "markdown", "id": "c54139af-0392-4dcf-9dfc-b1051bd9ec9e", "metadata": {}, "source": [ "Como conclusión, los autores escriben:\n", "\n", "*\"Cuando un modelo de lenguaje grande se entrena en un conjunto de datos grande y diverso que puede funcionar bien en muchos dominios y conjuntos de datos.*\n", "\n", "*En el desempeño de Zero-Shot, GPT-2 se desempeña bien en 7 de los 8 conjuntos de datos de modelado de lenguaje probados.*\n", "\n", "*La diversidad de tareas que el modelo es capaz de realizar en una configuración de disparo cero sugiere que alta capacidad modelos entrenados para maximizar la probabilidad de un variado corpus de texto comienzan a aprender a realizar un sorprendente cantidad de tareas sin necesidad de supervisión explícita\"*" ] }, { "attachments": {}, "cell_type": "markdown", "id": "94b3f616-de4e-4586-ba7a-4a030ab3a66f", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Modelo en Acción" ] }, { "cell_type": "code", "execution_count": 36, "id": "fa6614fb-ddc8-484a-9c24-61185ada0db8", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1e497f6426af4b7e90a349797d2e2d7c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| | 0.00/665 [00:00Ejemplo de Generación de Blogs Artificiales" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2d63be04-fa1e-4f76-9184-c161e28093e0", "metadata": {}, "source": [ "En Mac M1, este ejemplo tomó varios minutos para sus ejecución.\n", "\n", "**Utilícelo con cuidado.**" ] }, { "cell_type": "code", "execution_count": null, "id": "4feea6d3-a887-401a-8fbd-52ba741ea512", "metadata": {}, "outputs": [], "source": [ "from transformers import GPT2LMHeadModel, GPT2Tokenizer\n", "\n", "tokenizer = GPT2Tokenizer.from_pretrained(\"gpt2-large\")\n", "model = GPT2LMHeadModel.from_pretrained(\"gpt2-large\", pad_token_id=tokenizer.eos_token_id)\n", "\n", "topic = 'Benefits of Sleeping Early'\n", "\n", "input_ids = tokenizer.encode(topic, return_tensors='pt')\n", "\n", "# Generate Blog\n", "#max_lenth-Number of Words in the Article\n", "#num_beams-Number of different combination of words that can be chained together\n", "#no_repeat_ngram_size-No of words that be combined together and repeated, example: ['benefits of sleeping' can be repeated 2 times but not more ]\n", "\n", "\n", "output = model.generate(input_ids, max_length=200, num_beams=30, no_repeat_ngram_size=4, early_stopping=True)\n", "\n", "article_en = tokenizer.decode(output[0], skip_special_tokens=True)" ] }, { "cell_type": "code", "execution_count": 47, "id": "08fd1d0d-4d08-4171-9075-4586f34aedcb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Benefits of Sleeping Early in the Morning\n", "\n", "Sleeping early in the morning is one of the most important things you can do to improve your health and well-being. Here are some of the benefits of getting up earlier in the morning:\n", "\n", "Improves Sleep Quality\n", "\n", "A study published in the Journal of the American Medical Association (JAMA) found that people who get an early start in the morning are more likely to get a good night's sleep than those who get up later in the morning.\n", "\n", "According to the study, people who get up at 6:30 a.m. are less likely to wake up in the middle of the night than those who don't get up at all.\n", "\n", "People who get up early are also less likely to suffer from sleep apnea, a sleep disorder that makes it difficult for people to fall asleep.\n", "\n", "Reduces the Risk of Heart Disease\n", "\n", "One of the most common causes of death in the United States is\n" ] } ], "source": [ "print(article_en)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4de9cd5c-6d5b-4c57-b54e-299e072e45bf", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "### Fine-Tuning" ] }, { "attachments": {}, "cell_type": "markdown", "id": "44bf5374-6afd-4be4-ae1a-fd115cef5bf4", "metadata": {}, "source": [ "Para los interesados en Fine-Tuning GPT-2 para diversas tareas del NLU, recomendamos el siguiente enlace:\n", "\n", "* [Guide to fine-tuning Text Generation models: GPT-2, GPT-Neo and T5](https://towardsdatascience.com/guide-to-fine-tuning-text-generation-models-gpt-2-gpt-neo-and-t5-dc5de6b3bc5e)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b1251021-e291-47f8-9ea4-21a5501f7a47", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## Megatron y Turing-NLG" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3a0295d5-cc12-4d8d-890c-3006337c9efd", "metadata": {}, "source": [ "Siguiendo la escala de \"entre más grande, mejor\", los modelos posteriores que siguieron a GPT-2 fueron\n", "\n", "* [Megatron](https://github.com/NVIDIA/Megatron-LM), con 8.300 millones de parámetros\n", "* [Turing-NLG](https://www.microsoft.com/en-us/research/blog/turing-nlg-a-17-billion-parameter-language-model-by-microsoft/), con 17.000 millones de parámetros.\n", "\n", "Algunos de estos modelos han sido liberados, pero para los demás, hay alguna forma de pago.\n", "\n", "Para mayor detalle, puede ir a [Generate Chatbot training data with QBox — powered by Microsoft Turing NLG](https://medium.com/qbox-nlp-performance-tooling/generate-chatbot-training-data-with-qbox-powered-by-microsoft-turing-nlg-af69f7bfdd4d) o [Megatron HF 345m](https://huggingface.co/nvidia/megatron-gpt2-345m).\n", "\n", "Cada uno de estos modelos, ha demostrado mejorar las métricas del Zero-Shot en varios conjuntos de datos y tareas de NLU distintas.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e4c98113-4b12-483b-a53c-9c9ebf7e32a7", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "9ea40867-3d47-411d-bc43-c3ec167a04d3", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## GPT-3" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e697bd66-cd7c-46ae-9b8b-d2115828c3b7", "metadata": {}, "source": [ "Finalmente, la gran revolución reciente en ésta area, fue el modelo entrenado por el equipo de OpenAI, la tercera versión de la familia GPT y que ha sido de gran impacto a nivel mundial.\n", "\n", "Actualmente no es posible acceder al modelo y utlizarlo de manera libre, sino por medio de la API de OpenAI a la cual uno debe registrarse y cuenta con 18 dólares gratuitos para hacer pruebas.\n", "\n", "El paper de GPT-3 es bastante extenso (40 páginas, ignorando los apéndices), por lo que es buena idea ver el excelente siguiente video de Yannic Kilcher:\n", "\n", "* [GPT-3: Language Models are Few-Shot Learners (Paper Explained)](https://www.youtube.com/watch?v=SY5PvZrJhLE)\n", "\n", "Si no tiene acceso aún, le recomendamos aplicar y probar las posibilidades.\n", "\n", "A modo de información, colocamos algunas tablas de los resultados del paper:\n", "\n", "![gpt3_model](../Imagenes/gpt3_model.png)\n", "![gpt3_dataset](../Imagenes/gpt3_dataset.png)\n", "![zero_few_shot](../Imagenes/zero_few_shot.png)\n", "![gpt3_QA](../Imagenes/gpt3_QA.png)\n", "![gpt3_skills](../Imagenes/gpt3_skills.png)\n", "![lm_power_law](../Imagenes/lm_power_law.png)\n", "\n", "Como Bonus, mostraremos ejemplos a través de la API, a la cual hemos tenido reciente acceso.\n", "\n", "* [Welcome to OpenAI](https://beta.openai.com/overview)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "84ef4b56-e1ce-4973-a179-c7ed833e1f05", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d22257d7-f0ae-4b13-bd1f-2d1855d93d3e", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## OPT" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3a57776a-c93c-488b-874f-c7e7a78bee2b", "metadata": {}, "source": [ "Debido a la restricción de GPT-3 para usuarios comunes, Facebook (Ahora Meta) liberó un equivalente a GPT-3 hace algunos días.\n", "\n", "El paper se llama [OPT: Open Pre-trained Transformer Language Models](https://arxiv.org/pdf/2205.01068.pdf) y es un intento por la democratización de los modelos del estado del arte para toda la población (¿O qué opinan ustedes?).\n", "\n", "Según Meta, este modelo es comparable con GPT-3, a un costo de huella de carbón de 1/7 de la parte usada por GPT-3.\n", "\n", "Esto es un paso hacia la IA preocupada por el medio ambiente.\n", "\n", "Algo interesante de rescatar del paper (No es difícil de leer), es la comparación de toxicidad entre modelos:\n", "\n", "![opt_tox](../Imagenes/OPT_Tox.png)\n", "\n", "Para los interesados, pueden ir al [GitHub de OPT](https://github.com/facebookresearch/metaseq/tree/main/projects/OPT), bajarse los pesos de los modelos y requerir acceso al modelo completo a través de un formulario.\n", "\n", "En el paper prometer acceso a la comunidad científica." ] }, { "attachments": {}, "cell_type": "markdown", "id": "f92bb6e7-2c26-49c5-b5f8-48fb78eaaa81", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bc0a343d-8b19-4ccf-8b52-359e7a4e8a8e", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## BlenderBot" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4853c0be-32a0-483e-b41d-a9c82f0ed90c", "metadata": {}, "source": [ "Tener un modelo de lenguaje natural con resultados sorprendentes en el GLUE/SUPERGLUE u otros, no garantiza tener un chat-bot a la medida.\n", "\n", "Hay otras habilidades que deben explotarse: Por ejemplo, una buena conversación requiere una serie de habilidades que un conversador experto combina a la perfección: proporcionar puntos de conversación atractivos y escuchar a sus interlocutores, y mostrar conocimiento, empatía y personalidad de manera adecuada, manteniendo una personalidad coherente.\n", "\n", "Meta (Facebook en su tiempo), creó un modelo de varios tamaños (90M, 2.7B y 9.4B) que apunta a las recetas fundamentales de crear un chatbot eficiente.\n", "\n", "Su nombre es **BlenderBot**.\n", "\n", "Según el paper, un buen chatbot debe tener\n", "\n", "1. Habilidades de combinación (Blending Skills):\n", "\n", "\n", "Se pueden realizar grandes mejoras ajustando los datos que enfatizan las habilidades de conversación deseables. \n", "\n", "Se seleccionan tareas que hacen que el modelo se centre en la personalidad y el compromiso, el conocimiento y la empatía, logrando grandes ganancias mediante el uso de la recientemente introducida Configuración de Blended Skill Talk (BST), que se enfoca en esos aspectos al proporcionar datos de capacitación y conversaciones iniciales contexto (personajes y temas).\n", "\n", "Mientras que BST enfatiza características deseables, también mostramos esta afinación puede minimizar los rasgos indeseables aprendidos de grandes corpus, como la toxicidad.\n", "\n", "2. Estrategias de Generación:\n", "\n", "La elección del algoritmo de decodificación es de vital importancia, y dos modelos con la misma perplejidad, pero diferentes algoritmos de decodificación\n", "puede dar resultados muy diferentes.\n", "\n", "En particular se puede mostrar que la longitud de las declaraciones del bot son cruciales para los juicios humanos de calidad – demasiado cortas y las respuestas se consideran aburridas o mostrando una falta de interés, demasiado tiempo y el bot parece vacilar y no escuchar.\n", "\n", "Para la arquitectura, este modelo es un tipo seq2seq, que utiliza la misma arquitectura del transformer con un poly-encoder.\n", "\n", "La tokenización usada es la BPE.\n", "\n", "La arquitectura del modelo se describe a continuación:\n", "\n", "*\"Nuestro modelo de parámetros 9.4B tiene un codificador de 4 capas, un decodificador de 32 capas con 4096 incrustaciones dimensionales y 32 cabezas de atención. Nuestro modelo de parámetros 2.7B imita aproximadamente las elecciones arquitectónicas de Adiwardana et al. (2020), con 2 capas de codificador, 24 capas de decodificador, 2560 incrustaciones dimensionales y 32 cabezas de atención.\"*\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b431ce99-406f-4538-9201-475083261e75", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "8d269b97-ed42-4f31-93d8-1a36ed2607cb", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## BlenderBot2" ] }, { "attachments": {}, "cell_type": "markdown", "id": "41c9d42c-1adb-4b23-a9d7-c164a38b589c", "metadata": {}, "source": [ "BlenderBot2 es una modificación de BlenderBot que, entre otras, tiene acceso a internet para no incurrir en el fenómeno que sufren muchos modelos, conocido como **alucinar conocimiento**." ] }, { "attachments": {}, "cell_type": "markdown", "id": "d2ef0964-ce31-44b6-bae0-053f38e13e14", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f208ba3b-7cde-4a40-a3f4-1c13e22a75ae", "metadata": { "id": "a8844c02-b7d1-4411-8527-2ce9540931ba", "tags": [] }, "source": [ "## PaLM" ] }, { "attachments": {}, "cell_type": "markdown", "id": "bbf9349d-6a8b-4b6a-a851-55c5695431bd", "metadata": {}, "source": [ "Respecto a modelos grandes, HuggingFace tiene algo que decir en [Large Language Models: A New Moore's Law?](https://huggingface.co/blog/large-language-models).\n", "\n", "Quizás el modelo más grande hasta el momento, se llama PaLM y fue creado por Google hace menos de un mes.\n", "\n", "**El modelo tiene 540 mil millones de parámetros (540 billones en inglés).**\n", "\n", "Podemos acceder a:\n", "\n", "* Paper: [PaLM: Scaling Language Modeling with Pathways](https://arxiv.org/pdf/2204.02311.pdf)\n", "* Ejemplo demostrativo: [\n", "Integrated AI - PaLM by Google Research (Apr/2022) - Explaining jokes + Inference chaining (540B)](https://www.youtube.com/watch?v=kea2ATUEHH8)\n", "* GitHub educativo de lucidrains: [PaLM - Pytorch](https://github.com/lucidrains/PaLM-pytorch)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "36dbc7cd-be4d-46d5-a3d3-41803b14446e", "metadata": { "id": "0b4dfef6-d2b8-433f-a7c7-1a20bd4e2c2a" }, "source": [ "[[Volver]](#Contenido)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" } }, "nbformat": 4, "nbformat_minor": 5 }