{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "LFsN8RM-81OP" }, "source": [ "# π Homework 9: Text Generation & HuggingFace Spaces\n", "**MIS 769 - Big Data Analytics for Business | Spring 2026**\n", "\n", "**Points:** 20 | **Due:** See WebCampus for deadline\n", "\n", "**Author:** Richard Young, Ph.D. | UNLV Lee Business School\n", "\n", "**Compute:** GPU recommended β Spaces deployment is free\n", "\n", "---\n", "\n", "## What You'll Learn\n", "\n", "1. Use HuggingFace Transformers for text generation\n", "2. Understand generation parameters (temperature, top-k, top-p)\n", "3. Build an interactive demo with Gradio\n", "4. Deploy your application to HuggingFace Spaces\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": { "id": "4N9OKgOh81OQ" }, "source": [ "## From Notebook to Production\n", "\n", "This homework takes you through the full deployment pipeline β from experimenting with text generation in Colab, to building an interactive Gradio demo, to deploying a public application on HuggingFace Spaces.\n", "\n", "\n", "\n", "**The four stages:**\n", "1. **Local Development** β Experiment with models and generation parameters in Google Colab\n", "2. **Gradio Demo** β Wrap your model in an interactive UI with sliders and text inputs\n", "3. **HuggingFace Spaces** β Push your `app.py` to deploy with one command\n", "4. **Public URL** β Anyone in the world can use your application\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": { "id": "rUevVoHm81OQ" }, "source": [ "## Part 1: Text Generation (4 points)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 567, "referenced_widgets": [ "ad3a7e15a4074bb389cbe2c1e418fb47", "39bbef138d484166a9464e37b332a4ff", "a80f32e773704543a3da98c0109b4c6d", "ad5a710d553842c88b6e0febf7190b0a", "8a39298ac71441319c3da581e7055b6a", "d3df61c97b684c1db74f66387c5b5a0f", "414b22e0cc91448988ce660a5b3aa29b", "ebcc2b2c5af748f2a32fa8caca097cdc", "9fc03c2932ec4c2c8a0dad20c8644619", "38d31f9e6a3c49078108a274f698b12a", "b64084fedf3a4c63b9fffedcb48dea4d", "25180c25f023415888c8de0a8d215df9", "c79ff632c9bf43d58078658742a7726e", "442b34bc44f34587957d4dcaae583363", "6fe2b2de74c4479cbae52a7cd1bf08c7", "38df14a1410c47c9b76755107788e5ba", "a32d3653387a4034ab533f053d30696b", "2b3e002785a1450eb203e1a72ca9f988", "6545a3871f974cb09e65e5ce4ecc6090", "9d5167479d52457f993d5982ec518d98", "f702e2a95c5540f1bf5cc688d07f3ff8", "34605104a0e14229b48744a766fb90d0", "22429fe584b0471f9a257ff12dbebb94", "32bc8cd0874c4455a6bcbd9b68566354", "380e2157d5e8413ba192d4c8b09a08fe", "0212635835be4d08a0ff6d09506d6e71", "3ab234ca8c53456191e217ae00ef51be", "f56819bee3ee404190d89ab441fca724", "a0541f14ad044ea19cf53181a63cb7d6", "1ef1b2b7272844398611bba422d7eb5a", "7ccb4a1f74ed428cbd987ad4d38aa782", "48d03257f2414697a76d1c9e8aac55e5", "c109fa25049c4e60bd363f9599231a24", "740500ee7b104e309fbde222fe24138e", "673eabf330234f60968d004a0516c483", "eac4701013a14512bf857ac9ec07e65d", "f30468a3d3d749289d3b62911c2cfe73", "94e0f3a07d18444d84ee2cb4b27dd7c9", "3dec5e3d36bf49309f62704a8fef924e", "d288b43bbe1a4d6b88706b5c3888735a", "bf358e1bde9741a0af331bdcfcae57de", "f12ac07e1e2d4027a4edf1e037c719e0", "3bb3bb97f8f2459daf2eb61b92039bb1", "31820c763dc249b5bd7c6e65839a9197", "248278914d8f42bfbb8a9b7f8e70c714", "2931736c52524176857469780a8889e2", "e5f9b86a7f644abcad08f46858b65cb6", "dc1ab246b4fb48f995e0947c183b01b1", "1683178243e2494c8c5c548181fd1caa", "809109901448436cac03dec0659f7a61", "a7399b17a05548e58c8001fe7363a752", "e696a18f9926419cbe49ee9a644d51ce", "0dbf5823de294b78b9d116c7195f16f5", "237c6e653791467e872acf673a3ff535", "e024941c9689499bbb458bd212b579ec", "4ddb49a492934615a2a4ccd89a2c1371", "c270d42329384834a1a60f5b739d125f", "c091b43b1a054096920a30b659316c0e", "741580e71603404a9ce4c59e944b00b9", "82231601e4a84e5b85ad2b96f417d78f", "bb5c97c29fe84ab0acef16992dc20099", "8cf7b0cd1d9443f0835ef90cecd8b3d8", "1f32f63b6b0b48c0b81b1e1e196e9586", "272ac2119b3343e2a772d8824ac6c270", "698306c5a25544298947ab52d5013211", "93026e704cc54df1a371be4645feda85", "122f7e238e16402cb261d8395c5d8cd9", "c86817446c844deabebd80069483d58e", "7c4d5c7705fa4baa9eae7f3b48cf88fc", "13c78d38a52d4ea9832a5848d58c6883", "2546d55bd92248bf88336874415b3f43", "a66786240c704d0bad55e1b75bab8d1b", "de7cb811a5a54123ad1c2a3e4edc46fd", "790e206e3dc6403fb12f1e72df3abca6", "b4637216522c46e4bc486e2585c94adf", "9e73c1635509456887d0430d6fa23438", "dcbe459af6f6408ab458baa350709e90", "b4f0f045bdcf4922b998a283bc08cc60", "2e82c253e88b4379a05d246c4ebcb410", "df984d632e474c89afca9ef5f433ab71", "4924a5a90d02474db51e48870f21d151", "486c91cd5dc24206936732d4385825a1", "f95e2dc22f384698b0f95d4c62e767d5", "48bcdff92e774be38a51645a7407099d", "692d64f7502846878d3b275bae5d611d", "691218dbda5f45b08e36ed1b529f9472", "6417c16e656547048fe33da5795d04ef", "f88575b368cc42f297ef596c5903363c" ] }, "id": "TU2eQLRm81OR", "outputId": "d4da688e-f4d7-47d5-caad-3d1d8c255b3f" }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "03d186647408438da121033e0d9d98bb", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Loading weights: 0%| | 0/148 [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "β GPT-2 model loaded\n" ] } ], "source": [ "!pip install transformers torch gradio -q\n", "\n", "from transformers import pipeline\n", "\n", "# Load GPT-2 (small, works on CPU)\n", "generator = pipeline(\"text-generation\", model=\"gpt2\")\n", "\n", "print(\"β GPT-2 model loaded\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "pmV_I2K181OR", "outputId": "b3a559cf-c4eb-4f96-c61d-5f558c2dd9da" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Passing `generation_config` together with generation-related arguments=({'pad_token_id', 'max_new_tokens', 'do_sample'}) is deprecated and will be removed in future versions. Please pass either a `generation_config` object OR all generation parameters explicitly, but not both.\n", "Both `max_new_tokens` (=50) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "π TEXT GENERATION\n", "============================================================\n", "Prompt: \"The future of artificial intelligence\"\n", "\n", "Generated:\n", "The future of artificial intelligence and the future of the social contract is yet to be determined. The future of our society may or may not take many forms. We may have a new kind of social contract, our new political contract, our new economic contract, or perhaps even the\n" ] } ], "source": [ "# Basic text generation\n", "prompt = \"The future of artificial intelligence\"\n", "\n", "output = generator(\n", " prompt,\n", " max_new_tokens=50,\n", " do_sample=True,\n", " pad_token_id=50256 # GPT-2 fix\n", ")\n", "\n", "print(\"π TEXT GENERATION\")\n", "print(\"=\" * 60)\n", "print(f\"Prompt: \\\"{prompt}\\\"\")\n", "print(f\"\\nGenerated:\")\n", "print(output[0]['generated_text'])" ] }, { "cell_type": "markdown", "metadata": { "id": "I_N3vD_w81OR" }, "source": [ "## Part 2: Parameter Exploration (4 points)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "KS-e9HCB81OR", "outputId": "ab070add-856e-49fd-ff05-4a212bc0c156" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Passing `generation_config` together with generation-related arguments=({'pad_token_id', 'temperature', 'max_new_tokens', 'do_sample'}) is deprecated and will be removed in future versions. Please pass either a `generation_config` object OR all generation parameters explicitly, but not both.\n", "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n", "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "π TEMPERATURE COMPARISON\n", "============================================================\n", "\n", "Temperature 0.3:\n", " , the world was a place of peace and harmony. But now, the world is a place of w...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Temperature 0.7:\n", " , it was a small part of his life that would end up coming into fruition.\n", "\n", "In th...\n", "\n", "Temperature 1.2:\n", " he had thought his dreams would turn him, to the true power where his strength ...\n" ] } ], "source": [ "# Temperature comparison\n", "print(\"π TEMPERATURE COMPARISON\")\n", "print(\"=\" * 60)\n", "\n", "prompt = \"Once upon a time\"\n", "temperatures = [0.3, 0.7, 1.2]\n", "\n", "for temp in temperatures:\n", " output = generator(\n", " prompt,\n", " max_new_tokens=30,\n", " temperature=temp,\n", " do_sample=True,\n", " pad_token_id=50256\n", " )\n", " generated = output[0]['generated_text'][len(prompt):]\n", " print(f\"\\nTemperature {temp}:\")\n", " print(f\" {generated[:80]}...\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "aJnxPENL81OR", "outputId": "f74dbcd5-64a7-404e-8c3a-d6fa6d39ce6d" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Passing `generation_config` together with generation-related arguments=({'pad_token_id', 'top_k', 'max_new_tokens', 'do_sample', 'top_p'}) is deprecated and will be removed in future versions. Please pass either a `generation_config` object OR all generation parameters explicitly, but not both.\n", "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "π TOP-K AND TOP-P COMPARISON\n", "============================================================\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "top_k=10:\n", " , you might have a few friends who are going to get together and play a game tha...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "top_k=50:\n", " , when I was a kid, children would watch the movies on your computer screen and ...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Both `max_new_tokens` (=30) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "top_p=0.9:\n", " , the owners of the ships were full of hope and inspiration. They knew that if t...\n", "\n", "top_p=0.5:\n", " , I had been in a relationship with a woman who was a virgin. She was very attra...\n" ] } ], "source": [ "# Top-k and Top-p comparison\n", "print(\"π TOP-K AND TOP-P COMPARISON\")\n", "print(\"=\" * 60)\n", "\n", "configs = [\n", " {\"top_k\": 10, \"top_p\": 1.0, \"name\": \"top_k=10\"},\n", " {\"top_k\": 50, \"top_p\": 1.0, \"name\": \"top_k=50\"},\n", " {\"top_k\": 0, \"top_p\": 0.9, \"name\": \"top_p=0.9\"},\n", " {\"top_k\": 0, \"top_p\": 0.5, \"name\": \"top_p=0.5\"},\n", "]\n", "\n", "for cfg in configs:\n", " output = generator(\n", " prompt,\n", " max_new_tokens=30,\n", " top_k=cfg[\"top_k\"] if cfg[\"top_k\"] > 0 else None,\n", " top_p=cfg[\"top_p\"],\n", " do_sample=True,\n", " pad_token_id=50256\n", " )\n", " generated = output[0]['generated_text'][len(prompt):]\n", " print(f\"\\n{cfg['name']}:\")\n", " print(f\" {generated[:80]}...\")" ] }, { "cell_type": "markdown", "metadata": { "id": "56TfcoY681OR" }, "source": [ "### The Repetition Problem\n", "\n", "GPT-2 is notorious for getting stuck in loops β repeating the same phrase or sentence over and over. This happens because the model assigns high probability to tokens it has already generated (a feedback loop).\n", "\n", "**Repetition penalty** (`repetition_penalty`) solves this by reducing the probability of tokens that have already appeared. A value of `1.0` means no penalty (default), while `1.2`-`1.5` progressively discourages repetition.\n", "\n", "```\n", "repetition_penalty = 1.0 β \"The cat sat on the mat. The cat sat on the mat. The cat...\"\n", "repetition_penalty = 1.3 β \"The cat sat on the mat. It purred softly as sunlight streamed...\"\n", "```\n", "\n", "This is especially important for **longer generations** (100+ tokens) where loops are more likely to appear. Try running the same prompt with and without the penalty to see the difference." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "382eRViL81OR", "outputId": "8ecba49f-1108-4dc0-b2b4-7fb1f0e5eb91" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Passing `generation_config` together with generation-related arguments=({'pad_token_id', 'repetition_penalty', 'temperature', 'max_new_tokens', 'do_sample'}) is deprecated and will be removed in future versions. Please pass either a `generation_config` object OR all generation parameters explicitly, but not both.\n", "Both `max_new_tokens` (=80) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "π REPETITION PENALTY COMPARISON\n", "============================================================\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Both `max_new_tokens` (=80) and `max_length`(=50) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "No penalty (repetition_penalty=1.0):\n", " it had sold the $13.9 million stake in the business to an undisclosed buyer.\n", "\n", "The company's stock has fallen to $19.55 ...\n", "\n", "Penalty 1.3 (repetition_penalty=1.3):\n", " it had acquired the rights to run a high-tech communications service, Voice of America.\n", "\n", "\n", " (Photo: Google) Story Highli...\n" ] } ], "source": [ "# Repetition penalty comparison\n", "print(\"π REPETITION PENALTY COMPARISON\")\n", "print(\"=\" * 60)\n", "\n", "prompt = \"The company announced that\"\n", "penalties = [1.0, 1.3]\n", "\n", "for penalty in penalties:\n", " output = generator(\n", " prompt,\n", " max_new_tokens=80,\n", " temperature=0.7,\n", " repetition_penalty=penalty,\n", " do_sample=True,\n", " pad_token_id=50256\n", " )\n", " generated = output[0]['generated_text'][len(prompt):]\n", " label = \"No penalty\" if penalty == 1.0 else f\"Penalty {penalty}\"\n", " print(f\"\\n{label} (repetition_penalty={penalty}):\")\n", " print(f\" {generated[:120]}...\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "t6qf1K5B81OS", "outputId": "281d3afa-2bc6-4cfe-b065-171d2fd76388" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "π PARAMETER SUMMARY\n", "============================================================\n", "\n", "| Parameter | Effect | Typical Values |\n", "|--------------------|--------------------------------|----------------|\n", "| temperature | Higher = more random | 0.3-1.0 |\n", "| top_k | Limits token choices | 20-100 |\n", "| top_p | Nucleus sampling threshold | 0.8-0.95 |\n", "| repetition_penalty | Discourages repeated tokens | 1.0-1.5 |\n", "| max_tokens | Maximum output length | 50-500 |\n", "\n" ] } ], "source": [ "# Create a summary table\n", "print(\"\\nπ PARAMETER SUMMARY\")\n", "print(\"=\" * 60)\n", "print(\"\"\"\n", "| Parameter | Effect | Typical Values |\n", "|--------------------|--------------------------------|----------------|\n", "| temperature | Higher = more random | 0.3-1.0 |\n", "| top_k | Limits token choices | 20-100 |\n", "| top_p | Nucleus sampling threshold | 0.8-0.95 |\n", "| repetition_penalty | Discourages repeated tokens | 1.0-1.5 |\n", "| max_tokens | Maximum output length | 50-500 |\n", "\"\"\")" ] }, { "cell_type": "markdown", "metadata": { "id": "CN_z-G_H81OS" }, "source": [ "## Part 3: Gradio Interface (5 points)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "DtmP4y9V81OS", "outputId": "a137e54a-2406-40d6-ce49-5b2d713e7a23" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "π¨ GRADIO INTERFACE CREATED\n", "============================================================\n", "Run demo.launch() to start the interface\n" ] } ], "source": [ "import gradio as gr\n", "\n", "def generate_text(prompt, temperature, max_length):\n", " \"\"\"Generate text with specified parameters.\"\"\"\n", " if not prompt:\n", " return \"Please enter a prompt.\"\n", "\n", " result = generator(\n", " prompt,\n", " max_new_tokens=int(max_length),\n", " temperature=temperature,\n", " do_sample=True,\n", " pad_token_id=50256\n", " )\n", " return result[0]['generated_text']\n", "\n", "# Create Gradio interface\n", "demo = gr.Interface(\n", " fn=generate_text,\n", " inputs=[\n", " gr.Textbox(label=\"Prompt\", placeholder=\"Enter your prompt here...\", lines=2),\n", " gr.Slider(0.1, 1.5, value=0.7, step=0.1, label=\"Temperature\"),\n", " gr.Slider(20, 200, value=50, step=10, label=\"Max New Tokens\")\n", " ],\n", " outputs=gr.Textbox(label=\"Generated Text\", lines=5),\n", " title=\"π Text Generator\",\n", " description=\"Generate creative text using GPT-2. Adjust temperature for creativity.\",\n", " examples=[\n", " [\"The future of technology is\", 0.7, 50],\n", " [\"Once upon a time in a magical forest\", 0.9, 100],\n", " [\"Dear customer, thank you for\", 0.5, 50]\n", " ]\n", ")\n", "\n", "print(\"π¨ GRADIO INTERFACE CREATED\")\n", "print(\"=\" * 60)\n", "print(\"Run demo.launch() to start the interface\")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 595 }, "id": "5haebKej81OS", "outputId": "9002468e-e69d-4383-dff2-bd81b80df865" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "* Running on local URL: http://127.0.0.1:7860\n", "* Running on public URL: https://286b750b9905015c55.gradio.live\n", "\n", "This share link expires in 1 week. For free permanent hosting and GPU upgrades, run `gradio deploy` from the terminal in the working directory to deploy to Hugging Face Spaces (https://huggingface.co/spaces)\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "