From ef18679566d8a8afece9510961a9d76a37020ec1 Mon Sep 17 00:00:00 2001 From: Gabor Meresz Date: Sun, 29 Dec 2024 11:44:10 +0100 Subject: [PATCH] week3 way5 implementation with Gradio --- .../day5_with_Gradio.ipynb | 302 ++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 week3/community-contributions/day5_with_Gradio.ipynb diff --git a/week3/community-contributions/day5_with_Gradio.ipynb b/week3/community-contributions/day5_with_Gradio.ipynb new file mode 100644 index 0000000..12206dd --- /dev/null +++ b/week3/community-contributions/day5_with_Gradio.ipynb @@ -0,0 +1,302 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Create meeting minutes from an Audio file\n", + "\n", + "I downloaded some Denver City Council meeting minutes and selected a portion of the meeting for us to transcribe. You can download it here: \n", + "https://drive.google.com/file/d/1N_kpSojRR5RYzupz6nqM8hMSoEF_R7pU/view?usp=sharing\n", + "\n", + "If you'd rather work with the original data, the HuggingFace dataset is [here](https://huggingface.co/datasets/huuuyeah/meetingbank) and the audio can be downloaded [here](https://huggingface.co/datasets/huuuyeah/MeetingBank_Audio/tree/main).\n", + "\n", + "The goal of this product is to use the Audio to generate meeting minutes, including actions.\n", + "\n", + "For this project, you can either use the Denver meeting minutes, or you can record something of your own!\n", + "\n", + "## Please note:\n", + "\n", + "When you run the pip installs in the first cell below, you might get this error - it can be safely ignored - it sounds quite severe, but it doesn't seem to affect anything else in this project!\n", + "\n", + "\n", + "> ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "gcsfs 2024.10.0 requires fsspec==2024.10.0, but you have fsspec 2024.9.0 which is incompatible.\n", + "\n" + ], + "metadata": { + "id": "It89APiAtTUF" + } + }, + { + "cell_type": "code", + "source": [ + "!pip install -q requests torch bitsandbytes transformers sentencepiece accelerate openai httpx==0.27.2 gradio" + ], + "metadata": { + "id": "f2vvgnFpHpID" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "FW8nl3XRFrz0" + }, + "outputs": [], + "source": [ + "# imports\n", + "\n", + "import os\n", + "import requests\n", + "from openai import OpenAI\n", + "from google.colab import drive\n", + "from huggingface_hub import login\n", + "from google.colab import userdata\n", + "from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamer, BitsAndBytesConfig\n", + "import torch\n", + "import gradio as gr" + ] + }, + { + "cell_type": "code", + "source": [ + "# Constants\n", + "\n", + "AUDIO_MODEL = \"whisper-1\"\n", + "LLAMA = \"meta-llama/Meta-Llama-3.1-8B-Instruct\"" + ], + "metadata": { + "id": "q3D1_T0uG_Qh" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# New capability - connect this Colab to my Google Drive\n", + "# See immediately below this for instructions to obtain denver_extract.mp3\n", + "\n", + "drive.mount(\"/content/drive\")\n", + "audio_filename = \"/content/drive/MyDrive/llms/denver_extract.mp3\"" + ], + "metadata": { + "id": "Es9GkQ0FGCMt" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Download denver_extract.mp3\n", + "\n", + "You can either use the same file as me, the extract from Denver city council minutes, or you can try your own..\n", + "\n", + "If you want to use the same as me, then please download my extract here, and put this on your Google Drive: \n", + "https://drive.google.com/file/d/1N_kpSojRR5RYzupz6nqM8hMSoEF_R7pU/view?usp=sharing\n" + ], + "metadata": { + "id": "HTl3mcjyzIEE" + } + }, + { + "cell_type": "code", + "source": [ + "# Sign in to HuggingFace Hub\n", + "\n", + "hf_token = userdata.get('HF_TOKEN')\n", + "login(hf_token, add_to_git_credential=True)" + ], + "metadata": { + "id": "xYW8kQYtF-3L" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Sign in to OpenAI using Secrets in Colab\n", + "\n", + "openai_api_key = userdata.get('OPENAI_API_KEY')\n", + "openai = OpenAI(api_key=openai_api_key)" + ], + "metadata": { + "id": "qP6OB2OeGC2C" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Initialize Llama model and tokenizer\n", + "\n", + "quant_config = BitsAndBytesConfig(\n", + " load_in_4bit=True,\n", + " bnb_4bit_use_double_quant=True,\n", + " bnb_4bit_compute_dtype=torch.bfloat16,\n", + " bnb_4bit_quant_type=\"nf4\"\n", + ")\n", + "\n", + "tokenizer = AutoTokenizer.from_pretrained(LLAMA)\n", + "tokenizer.pad_token = tokenizer.eos_token\n", + "\n", + "model = AutoModelForCausalLM.from_pretrained(\n", + " LLAMA,\n", + " device_map=\"auto\",\n", + " quantization_config=quant_config\n", + ")" + ], + "metadata": { + "id": "hgQBeIYUyaqj" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Generate meeting minutes\n", + "\n", + "def generate_minutes(transcription, model, tokenizer, progress=gr.Progress()):\n", + " progress(0.6, desc=\"Generating meeting minutes from transcript...\")\n", + "\n", + " system_message = \"You are an assistant that produces minutes of meetings from transcripts, with summary, key discussion points, takeaways and action items with owners, in markdown.\"\n", + " user_prompt = f\"Below is an extract transcript of a meeting. Please write minutes in markdown, including a summary with attendees, location and date; discussion points; takeaways; and action items with owners.\\n{transcription}\"\n", + "\n", + " messages = [\n", + " {\"role\": \"system\", \"content\": system_message},\n", + " {\"role\": \"user\", \"content\": user_prompt}\n", + " ]\n", + "\n", + " inputs = tokenizer.apply_chat_template(messages, return_tensors=\"pt\").to(\"cuda\")\n", + " outputs = model.generate(inputs, max_new_tokens=2000)\n", + " response = tokenizer.decode(outputs[0])\n", + "\n", + " # Clean up the response, keep only the minutes\n", + " progress(0.9, desc=\"Cleaning and formatting minutes...\")\n", + " response = response.split(\"<|end_header_id|>\")[-1].strip().replace(\"<|eot_id|>\",\"\")\n", + "\n", + " return response" + ], + "metadata": { + "id": "u9aFA7tjy3Ri" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Transcribe the uploaded audio file using OpenAI's Whisper model\n", + "\n", + "def transcribe_audio(audio_path, progress=gr.Progress()):\n", + " progress(0.3, desc=\"Creating transcript from audio...\")\n", + "\n", + " try:\n", + " with open(audio_path, \"rb\") as audio_file:\n", + " transcription = openai.audio.transcriptions.create(\n", + " model=AUDIO_MODEL,\n", + " file=audio_file,\n", + " response_format=\"text\"\n", + " )\n", + " return transcription\n", + " except Exception as e:\n", + " return f\"Error during transcription: {str(e)}\"" + ], + "metadata": { + "id": "OEuqR90Vy4AZ" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Process the uploaded audio file, transcribe it, and generate meeting minutes\n", + "\n", + "def process_upload(audio_file, progress=gr.Progress()):\n", + " progress(0.1, desc=\"Starting process...\")\n", + "\n", + " if audio_file is None:\n", + " return \"Please upload an audio file.\"\n", + "\n", + " try:\n", + " # Check file format\n", + " if not str(audio_file).lower().endswith('.mp3'):\n", + " return \"Please upload an MP3 file.\"\n", + "\n", + " # Get transcription\n", + " transcription = transcribe_audio(audio_file)\n", + " if transcription.startswith(\"Error\"):\n", + " return transcription\n", + "\n", + " # Generate minutes\n", + " minutes = generate_minutes(transcription, model, tokenizer)\n", + " progress(1.0, desc=\"Process complete!\")\n", + " return minutes\n", + "\n", + " except Exception as e:\n", + " return f\"Error processing file: {str(e)}\"" + ], + "metadata": { + "id": "lmdsy2iDy5d7" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Create Gradio interface\n", + "\n", + "interface = gr.Interface(\n", + " fn=process_upload,\n", + " inputs=gr.Audio(type=\"filepath\", label=\"Upload MP3 File\", format=\"mp3\"),\n", + " outputs=gr.Markdown(label=\"Meeting Minutes\", min_height=60),\n", + " title=\"Meeting Minutes Generator\",\n", + " description=\"Upload an MP3 recording of your meeting to get AI-generated meeting minutes. This process may take a few minutes.\",\n", + " flagging_mode=\"never\"\n", + ")" + ], + "metadata": { + "id": "k2U2bWtey7Yo" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Launch Gradio interface\n", + "\n", + "interface.launch()" + ], + "metadata": { + "id": "X3JbzRNRy9oG" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file