186 lines
5.8 KiB
Plaintext
186 lines
5.8 KiB
Plaintext
{
|
|
"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",
|
|
"For this project, the UI allows you to either upload meeting minutes, or record something of your own!"
|
|
],
|
|
"metadata": {
|
|
"id": "MYOLn_FzYAF4"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"# --- Install deps ---\n",
|
|
"!pip install -q gradio torch==2.5.1+cu124 torchvision==0.20.1+cu124 torchaudio==2.5.1+cu124 --index-url https://download.pytorch.org/whl/cu124\n",
|
|
"!pip install -q requests bitsandbytes==0.46.0 transformers==4.48.3 accelerate==1.3.0 openai"
|
|
],
|
|
"metadata": {
|
|
"id": "M01YO75ITfXF"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"# --- Imports ---\n",
|
|
"import gradio as gr\n",
|
|
"import torch\n",
|
|
"from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamer, BitsAndBytesConfig\n",
|
|
"from openai import OpenAI\n",
|
|
"from huggingface_hub import login\n",
|
|
"from google.colab import userdata\n",
|
|
"from google.colab import drive\n",
|
|
"import os"
|
|
],
|
|
"metadata": {
|
|
"id": "DGE8_oAwZJBo"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"# --- Constants ---\n",
|
|
"AUDIO_MODEL = \"whisper-1\"\n",
|
|
"LLAMA = \"meta-llama/Meta-Llama-3.1-8B-Instruct\""
|
|
],
|
|
"metadata": {
|
|
"id": "JPu-aNxDTmDi"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"# --- Auth ---\n",
|
|
"# assumes Colab userdata or your own env vars\n",
|
|
"hf_token = userdata.get('HF_TOKEN')\n",
|
|
"login(hf_token, add_to_git_credential=True)"
|
|
],
|
|
"metadata": {
|
|
"id": "JfWUrEVJTmET"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"openai_api_key = userdata.get('OPENAI_API_KEY')\n",
|
|
"openai = OpenAI(api_key=openai_api_key)"
|
|
],
|
|
"metadata": {
|
|
"id": "AiUtJ0mjTpVE"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"# --- Model setup ---\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",
|
|
"model = AutoModelForCausalLM.from_pretrained(\n",
|
|
" LLAMA, device_map=\"auto\", quantization_config=quant_config\n",
|
|
")"
|
|
],
|
|
"metadata": {
|
|
"id": "hMb4dggMW2s5"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"id": "XTEW5qAwRN4Y"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# --- Processing function ---\n",
|
|
"def process_meeting(audio_file):\n",
|
|
" # Step 1: Transcribe\n",
|
|
" with open(audio_file, \"rb\") as f:\n",
|
|
" transcription = openai.audio.transcriptions.create(\n",
|
|
" model=AUDIO_MODEL, file=f, response_format=\"text\"\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Step 2: Prepare prompt\n",
|
|
" system_message = (\n",
|
|
" \"You are an assistant that produces minutes of meetings from transcripts, \"\n",
|
|
" \"with summary, key discussion points, takeaways and action items with owners, \"\n",
|
|
" \"in markdown.\"\n",
|
|
" )\n",
|
|
" user_prompt = (\n",
|
|
" f\"Below is an extract transcript of a meeting. Please write minutes in markdown, \"\n",
|
|
" f\"including a summary with attendees, location and date; discussion points; \"\n",
|
|
" f\"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",
|
|
" # Step 3: Run through LLaMA\n",
|
|
" inputs = tokenizer.apply_chat_template(messages, return_tensors=\"pt\").to(\"cuda\")\n",
|
|
" streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)\n",
|
|
" outputs = model.generate(inputs, max_new_tokens=2000)\n",
|
|
"\n",
|
|
" response = tokenizer.decode(outputs[0], skip_special_tokens=True)\n",
|
|
" return response\n",
|
|
"\n",
|
|
"# --- Gradio UI ---\n",
|
|
"with gr.Blocks() as demo:\n",
|
|
" gr.Markdown(\"## 📝 Meeting Minutes Generator\\nUpload an audio file and get structured meeting minutes.\")\n",
|
|
" with gr.Row():\n",
|
|
" audio_in = gr.Audio(type=\"filepath\", label=\"Upload Meeting Audio\")\n",
|
|
" btn = gr.Button(\"Generate Minutes\")\n",
|
|
" md_out = gr.Markdown()\n",
|
|
"\n",
|
|
" btn.click(fn=process_meeting, inputs=audio_in, outputs=md_out)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"source": [
|
|
"demo.launch()"
|
|
],
|
|
"metadata": {
|
|
"id": "Yh4-imrmY8MH"
|
|
},
|
|
"execution_count": null,
|
|
"outputs": []
|
|
}
|
|
]
|
|
} |