{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [], "gpuType": "T4", "authorship_tag": "ABX9TyPNQJbT8chmsjYoacF3B3Ep", "include_colab_link": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" }, "accelerator": "GPU" }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "source": [ "# noise2music-inspired automatic music captioning\n", "\n", "In [noise2music](https://google-research.github.io/noise2music/), the training dataset is created by pseudo-labeling a vast collection of unlabeled music audio using two advanced deep learning models. A large language model generates a diverse set of general music-related descriptive sentences to serve as potential captions. These captions are then matched to individual music clips through zero-shot classification, leveraging a pre-trained joint embedding model designed for music and text.\n", "\n", "So being curious, let's try the following:\n", "\n", "1. Generate a lot of music descriptions with a Meta Llama 3.2 LLM.\n", "1. Embed the generated music descriptions with a LAION CLAP text encoder.\n", "1. Index the text embeddings for nearest neighbor retrieval with FAISS.\n", "1. Use the corresponding audio encoder to embed an audio example.\n", "1. Use the audio embedding as search query for retrieving text embeddings.\n", "\n", "**Could this simple method produce reasonable audio captions?**" ], "metadata": { "id": "EVsGy9kxKMn-" } }, { "cell_type": "code", "source": [ "pip install -q datasets faiss-cpu" ], "metadata": { "id": "vhPejzFwbCo1" }, "execution_count": 1, "outputs": [] }, { "cell_type": "code", "source": [ "import torch\n", "import faiss\n", "import transformers\n", "import datasets\n", "import polars as pl\n", "import librosa as lr\n", "import numpy as np\n", "import tqdm.auto as tqdm\n", "import seaborn as sns\n", "\n", "# Configure plotting.\n", "pl.Config.set_fmt_str_lengths(256)\n", "sns.set_style(\"ticks\")\n", "sns.set_theme(\"notebook\")\n", "\n", "# Download some example audio files.\n", "dataset = datasets.load_dataset(\"marsyas/gtzan\", trust_remote_code=True)\n", "\n", "# Download a pretrained text generation model.\n", "text_generator = transformers.pipeline(\n", " task=\"text-generation\",\n", " model=\"meta-llama/Llama-3.2-1B-Instruct\",\n", " torch_dtype=torch.bfloat16,\n", " device_map=\"auto\",\n", ")\n", "\n", "# Download a pretrained CLAP model.\n", "clap_model = transformers.ClapModel.from_pretrained(\"laion/larger_clap_general\")\n", "clap_processor = transformers.ClapProcessor.from_pretrained(\"laion/larger_clap_general\")" ], "metadata": { "id": "Ktlv3YEs9agI" }, "execution_count": 2, "outputs": [] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 147 }, "id": "yrF4CdDk8irv", "outputId": "a634a9f2-66cf-49de-fdf7-0652998e5f00" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "Setting `pad_token_id` to `eos_token_id`:None for open-end generation.\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ "shape: (1, 1)\n", "┌──────────────────────────────────────────────────────────────────────────────────────────────────┐\n", "│ generated_text │\n", "│ --- │\n", "│ str │\n", "╞══════════════════════════════════════════════════════════════════════════════════════════════════╡\n", "│ The piece features a haunting piano melody, punctuated by sparse strings and a subtle, pulsing │\n", "│ bass line that creates an eerie, atmospheric backdrop for a whispered vocal │\n", "└──────────────────────────────────────────────────────────────────────────────────────────────────┘" ], "text/html": [ "
\n", "shape: (1, 1)
generated_text
str
"The piece features a haunting piano melody, punctuated by sparse strings and a subtle, pulsing bass line that creates an eerie, atmospheric backdrop for a whispered vocal"
" ] }, "metadata": {}, "execution_count": 3 } ], "source": [ "# Generate a lot of music descriptions.\n", "messages = [\n", " {\"role\": \"system\", \"content\": \"You are a music reviewer who is specific, brief and accurate.\"},\n", " {\"role\": \"user\", \"content\": \"Imagine any random piece of music and describe how it sounds in one sentence without mentioning the name or artist.\"},\n", "]\n", "descriptions = text_generator(\n", " messages,\n", " num_return_sequences=1000,\n", " return_full_text=False,\n", " do_sample=True,\n", " num_beams=1,\n", " max_new_tokens=32,\n", ")\n", "descriptions = pl.DataFrame(descriptions)\n", "\n", "# Save the descriptions to file.\n", "descriptions.write_parquet(\"music_descriptions.parquet\")\n", "descriptions.sample()" ] }, { "cell_type": "code", "source": [ "num_dimensions = clap_model.config.projection_dim\n", "index = faiss.IndexFlatL2(num_dimensions)" ], "metadata": { "id": "WFJIhAWJ0unl" }, "execution_count": 4, "outputs": [] }, { "cell_type": "code", "source": [ "# Tokenize text descriptions.\n", "inputs = clap_processor(text=descriptions[\"generated_text\"].to_list(), return_tensors=\"pt\", padding=True)\n", "\n", "# Populate local vector database.\n", "batch_size = 8\n", "for i in tqdm.trange(0, len(inputs[\"input_ids\"]), batch_size, desc=\"Indexing descriptions\"):\n", " input_ids = inputs[\"input_ids\"][i:i + batch_size]\n", " attention_mask = inputs[\"attention_mask\"][i:i + batch_size]\n", "\n", " # Embed the tokens.\n", " text_embeddings = clap_model.get_text_features(input_ids, attention_mask)\n", "\n", " # Add embeddings to the index.\n", " index.add(text_embeddings.numpy(force=True))" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 49, "referenced_widgets": [ "8169284539774f2ca1d46492faee3b4a", "a8353dd195154f95b98066a0bcb8bb2b", "b68893e982f8455e8d4c4bcf4062bfde", "8e6add65bea04b3fbae40b7febb47a77", "9d007a2cd86b45709fe2273211bd89b7", "57454396c13042cea979f0b6b8003dda", "6387af3665084af08b3c3e09662a0ff4", "af1b1b90c1024a47abed21819ac2fe41", "9429673b334e4fc7a43774b9d0dfc9c4", "6658519e4ceb45adb7991cf5f2b2897b", "56923a5e99b44bc4834a750a97651e6b" ] }, "id": "-vzUKMwoIAyq", "outputId": "f8f6c1f1-fe9c-4068-8d5c-ec21ba91a461" }, "execution_count": 5, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "Indexing descriptions: 0%| | 0/125 [00:00\n", "shape: (5, 2)
generated_textscores
strf32
"This piece of music features a haunting, atmospheric arrangement of eerie whispers and dissonant harmonies, punctuated by sudden, percussive bursts of sound that"2.301279
"The piece is a haunting, atmospheric soundscape of pulsing synthesizers, eerie whispers, and a steady, pulsing heartbeat, evoking a sense of fore"2.252909
"This piece features a haunting, atmospheric soundscape of whispers and creaks, punctuated by a sparse, pulsing rhythm that gradually builds into a crescendo"2.249522
"The piece features a mesmerizing blend of eerie whispers, pulsating electronic beats, and haunting vocal harmonies that create an unsettling atmosphere, gradually building towards a dis"2.237405
"This 5-minute composition features a gradual build-up of atmospheric textures, with layers of haunting piano and whispery vocals gradually giving way to a driving, pulsing"2.235468
" ] }, "metadata": {}, "execution_count": 8 } ] }, { "cell_type": "code", "source": [ "sns.histplot(similarities[0], bins=max_results//100);" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 434 }, "id": "WULzrBDjS-HQ", "outputId": "c3c4c4cb-861d-4fed-d4c7-d30e37cfbb01" }, "execution_count": 9, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "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\n" }, "metadata": {} } ] } ] }