{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d31d8850",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:42:48.498319Z",
     "start_time": "2024-01-18T02:42:48.496832Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:46:25.749661Z",
     "iopub.status.busy": "2025-04-21T23:46:25.749238Z",
     "iopub.status.idle": "2025-04-21T23:46:25.754944Z",
     "shell.execute_reply": "2025-04-21T23:46:25.754491Z",
     "shell.execute_reply.started": "2025-04-21T23:46:25.749641Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7cd4c0dd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:42:53.666867Z",
     "start_time": "2024-01-18T02:42:48.821513Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:46:26.461595Z",
     "iopub.status.busy": "2025-04-21T23:46:26.461225Z",
     "iopub.status.idle": "2025-04-21T23:46:38.456476Z",
     "shell.execute_reply": "2025-04-21T23:46:38.455787Z",
     "shell.execute_reply.started": "2025-04-21T23:46:26.461579Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/tony/anaconda3/envs/suno_env_dev/lib/python3.10/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "import tqdm\n",
    "import math\n",
    "import torch\n",
    "import random\n",
    "import funcy\n",
    "import copy\n",
    "import gc\n",
    "import re\n",
    "import json\n",
    "import tempfile\n",
    "import collections\n",
    "from collections import Counter\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import fasttext\n",
    "from joblib import Parallel, delayed\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from suno_utils.audio import Audio\n",
    "from suno_utils.utils.text import (\n",
    "    write_jsonl,\n",
    "    read_jsonl,\n",
    "    write_json,\n",
    "    read_json,\n",
    "    normalize_whitespace,\n",
    ")\n",
    "from suno_utils.utils.lyrics import remove_speakers\n",
    "from suno_utils.utils.s3 import read_from_s3, check_s3_file_exists, open_from_s3\n",
    "from suno_utils.utils.tokenizers import tokenize\n",
    "from suno_utils.harvest.youtube.constants.text_lang import BASE_TO_FASTTEXT_REMAP\n",
    "from suno_utils.utils.metrics import get_cer\n",
    "from suno_utils.tasks.hoot import (\n",
    "    parse_lyrics,\n",
    "    legacy_parse_lyrics,\n",
    "    EMBEDDING_RATE as HOOT_EMBEDDING_RATE,\n",
    ")\n",
    "from suno_utils.utils.lyrics import remove_speakers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d6518a0b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:42:56.344509Z",
     "start_time": "2024-01-18T02:42:53.668461Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:46:38.457798Z",
     "iopub.status.busy": "2025-04-21T23:46:38.457495Z",
     "iopub.status.idle": "2025-04-21T23:46:38.460426Z",
     "shell.execute_reply": "2025-04-21T23:46:38.459924Z",
     "shell.execute_reply.started": "2025-04-21T23:46:38.457781Z"
    }
   },
   "outputs": [],
   "source": [
    "# If run language detection, uncomment this\n",
    "# LANG_ID_MODEL_FP = \"s3://suno-data/georg/trained_models/chirp_v1/lid.176.bin\"\n",
    "# text_lang_model = read_from_s3(LANG_ID_MODEL_FP, read_f=fasttext.load_model)\n",
    "# def _get_text_lang(text):\n",
    "#     \"\"\"get probability of input language for text\"\"\"\n",
    "#     text = text.replace(\"’\", \"'\").lower()\n",
    "#     text = re.sub(r\"\\[.+?\\]\", \" \", text)\n",
    "#     text = normalize_whitespace(text)\n",
    "#     out = text_lang_model.predict(text, k=1)\n",
    "#     lang_str = out[0][0]\n",
    "#     p_lang = out[1][0]\n",
    "#     lang = lang_str.split(\"__\")[-1]\n",
    "#     lang = BASE_TO_FASTTEXT_REMAP.get(lang, lang)\n",
    "#     #     if p_lang >= 0.8:\n",
    "#     #         return lang\n",
    "#     return p_lang, lang"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9d50793",
   "metadata": {},
   "source": [
    "## load all 3 infos together"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "238ff7dc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-21T23:46:38.461116Z",
     "iopub.status.busy": "2025-04-21T23:46:38.460974Z",
     "iopub.status.idle": "2025-04-21T23:48:09.223671Z",
     "shell.execute_reply": "2025-04-21T23:48:09.222989Z",
     "shell.execute_reply.started": "2025-04-21T23:46:38.461103Z"
    }
   },
   "outputs": [],
   "source": [
    "with open(\"/home/tony/Data/Hoot/deezer_metas.json\", \"r\") as fp:\n",
    "    deezer_metas = json.load(fp)\n",
    "with open(\"/home/tony/Data/Hoot/discogs_metas.json\", \"r\") as fp:\n",
    "    discogs_metas = json.load(fp)\n",
    "with open(\"/home/tony/Data/Hoot/genius_metas.json\", \"r\") as fp:\n",
    "    genius_metas = json.load(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "77edb668",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:09.225230Z",
     "iopub.status.busy": "2025-04-21T23:48:09.224933Z",
     "iopub.status.idle": "2025-04-21T23:48:10.466079Z",
     "shell.execute_reply": "2025-04-21T23:48:10.465415Z",
     "shell.execute_reply.started": "2025-04-21T23:48:09.225213Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1835250/1835250 [00:00<00:00, 5061154.83it/s]\n",
      "100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 761670/761670 [00:00<00:00, 3544303.33it/s]\n",
      "100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 2154863/2154863 [00:00<00:00, 3763228.85it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total metas: 4751783\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "metas = []\n",
    "for meta in tqdm.tqdm(genius_metas):\n",
    "    meta[\"dataset\"] = \"genius\"\n",
    "    metas.append(meta)\n",
    "for meta in tqdm.tqdm(deezer_metas):\n",
    "    meta[\"dataset\"] = \"deezer\"\n",
    "    metas.append(meta)\n",
    "for meta in tqdm.tqdm(discogs_metas):\n",
    "    meta[\"dataset\"] = \"discogs\"\n",
    "    metas.append(meta)\n",
    "print(f\"Total metas: {len(metas)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "aa66a026",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:02.592483Z",
     "start_time": "2024-01-09T15:10:01.314852Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:10.466896Z",
     "iopub.status.busy": "2025-04-21T23:48:10.466745Z",
     "iopub.status.idle": "2025-04-21T23:48:12.828484Z",
     "shell.execute_reply": "2025-04-21T23:48:12.827826Z",
     "shell.execute_reply.started": "2025-04-21T23:48:10.466881Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('en', 2699688), ('es', 456982), ('pt', 228395), ('fr', 182036), ('de', 147990), ('ru', 124696), ('it', 111616), ('ja', 104777), ('pl', 87009), ('ko', 78093)]\n"
     ]
    }
   ],
   "source": [
    "# check language counts\n",
    "c = Counter([m[\"lang\"] for m in metas])\n",
    "print(c.most_common(10))\n",
    "# filter out languages with less than 50 clips\n",
    "metas_map = {m[\"id\"]: m for m in metas if c[m[\"lang\"]] > 50}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2b486253",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:19.399035Z",
     "start_time": "2024-01-09T15:10:02.594795Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:12.829291Z",
     "iopub.status.busy": "2025-04-21T23:48:12.829132Z",
     "iopub.status.idle": "2025-04-21T23:48:15.956305Z",
     "shell.execute_reply": "2025-04-21T23:48:15.955615Z",
     "shell.execute_reply.started": "2025-04-21T23:48:12.829274Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4664652 filtered clips\n",
      "en 2657936 162264 hours\n",
      "es 450732 27367 hours\n",
      "pt 224325 13670 hours\n",
      "fr 175404 10470 hours\n",
      "de 139857 8261 hours\n",
      "ru 123904 6698 hours\n",
      "it 106457 6431 hours\n",
      "ja 101134 7240 hours\n",
      "pl 86878 5030 hours\n",
      "ko 73218 4700 hours\n"
     ]
    }
   ],
   "source": [
    "print(len(metas_map), \"filtered clips\")\n",
    "c = Counter([m[\"lang\"] for m in metas_map.values()])\n",
    "for k, v in c.most_common(10):\n",
    "    print(\n",
    "        k,\n",
    "        c[k],\n",
    "        round(sum(m[\"duration_s\"] for m in metas if m[\"lang\"] == k) / 60 / 60),\n",
    "        \"hours\",\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c2ce5d00",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:19.404006Z",
     "start_time": "2024-01-09T15:10:19.401076Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:15.957171Z",
     "iopub.status.busy": "2025-04-21T23:48:15.957017Z",
     "iopub.status.idle": "2025-04-21T23:48:16.058140Z",
     "shell.execute_reply": "2025-04-21T23:48:16.057468Z",
     "shell.execute_reply.started": "2025-04-21T23:48:15.957156Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': '1mwGic4sL-U', 'lyrics': '孩子从大人手上\\n牵走了所有愿望\\n谁想要都不让\\n长大以后他会原谅\\n童话里美丽的谎\\n却已不再上当\\n\\n悲剧把完整的美好破坏给人观赏\\n先大病一场 才珍惜健康\\n喜剧把悲剧又当成笑话去讲\\n总有人笑得夸张 有人哭无声响\\n\\n唔 再念念不忘\\n唔 未必有回响\\n\\n不如就\\nGoodbye and Farewell(Farewell Farewell)\\n别回望(若那样 结果 会怎样)\\nGoodbye and Farewell(Farewell Farewell)\\n别佯装(多冤枉 多难 放)\\n\\n悲剧把完整的美好破坏给人观赏\\n先大病一场 才珍惜健康\\n喜剧把悲剧又当成笑话去讲\\n总有人笑得夸张 有人哭无声响\\n\\nGoodbye and Farewell(Farewell Farewell)\\n别回望(若那样 结果 会怎样)\\nGoodbye and Farewell(Farewell Farewell)\\n别佯装(多冤枉 多难 放)\\n\\n幻灭过几个偶像\\n破碎过几次梦想\\n人各有各的去向\\n在人前漂亮风光\\n别过头暗自的疗伤\\n就是所谓成长\\n\\n这是所谓成长\\n\\n这是所谓成长', 'duration_s': 241, 'lang': 'zh', 'audio_filepath': 's3://suno-data/shared/nfdg/1mwGic4sL-U/artists/songs/audio/1mwGic4sL-U/audio.webm', 'dataset': 'discogs'}\n"
     ]
    }
   ],
   "source": [
    "for m in metas[::-1]:\n",
    "    if m[\"lang\"] == \"zh\":\n",
    "        print(m)\n",
    "        break"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "346cc768",
   "metadata": {},
   "source": [
    "# Pack the data\n",
    "format to save to:\n",
    "{\"audio_filepath\": \"./an4/wav/an4_clstk/fash/an251-fash-b.wav\", \"duration\": 1.0, \"text\": \"yes\"}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "71df5d56",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:20.258192Z",
     "start_time": "2024-01-09T15:10:19.486945Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:52.714559Z",
     "iopub.status.busy": "2025-02-10T21:38:52.714231Z",
     "iopub.status.idle": "2025-02-10T21:38:52.758887Z",
     "shell.execute_reply": "2025-02-10T21:38:52.758396Z",
     "shell.execute_reply.started": "2025-02-10T21:38:52.714543Z"
    }
   },
   "outputs": [],
   "source": [
    "# # this will also take 2 min...\n",
    "# pre_download_val_metas = read_jsonl(\"/app/suno/data/audio_2ch_48khz_lg/metas_val.jsonl\")\n",
    "# pre_download_train_metas = read_jsonl(\n",
    "#     \"/app/suno/data/audio_2ch_48khz_lg/metas_tr.jsonl\"\n",
    "# )\n",
    "# downloaded_ids_to_info = {}\n",
    "# for download_meta in pre_download_train_metas:\n",
    "#     if download_meta[\"original_id\"] not in downloaded_ids_to_info:\n",
    "#         downloaded_ids_to_info[download_meta[\"original_id\"]] = download_meta\n",
    "# for download_meta in pre_download_val_metas:\n",
    "#     if download_meta[\"original_id\"] not in downloaded_ids_to_info:\n",
    "#         downloaded_ids_to_info[download_meta[\"original_id\"]] = download_meta\n",
    "# downloaded_ids = set(downloaded_ids_to_info.keys())\n",
    "# print(len(downloaded_ids))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9870b504",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:52.759681Z",
     "iopub.status.busy": "2025-02-10T21:38:52.759446Z",
     "iopub.status.idle": "2025-02-10T21:38:52.802125Z",
     "shell.execute_reply": "2025-02-10T21:38:52.801660Z",
     "shell.execute_reply.started": "2025-02-10T21:38:52.759667Z"
    }
   },
   "outputs": [],
   "source": [
    "# sum(\n",
    "#     download_meta[\"dataset\"] == \"genius_hq\"\n",
    "#     for download_meta in pre_download_train_metas\n",
    "# )\n",
    "# subset_meta = [\n",
    "#     m for m in metas if (m[\"id\"] in downloaded_ids)\n",
    "# ]  # and m[\"lang\"] == \"en\")]\n",
    "# print(len(subset_meta))\n",
    "# 986464"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c8227733",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:20.872851Z",
     "start_time": "2024-01-09T15:10:20.261963Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:52.803015Z",
     "iopub.status.busy": "2025-02-10T21:38:52.802656Z",
     "iopub.status.idle": "2025-02-10T21:38:52.911709Z",
     "shell.execute_reply": "2025-02-10T21:38:52.911150Z",
     "shell.execute_reply.started": "2025-02-10T21:38:52.803000Z"
    }
   },
   "outputs": [],
   "source": [
    "subset_meta = metas.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2f9e4207",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:21.009129Z",
     "start_time": "2024-01-09T15:10:20.874879Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:38:42.681961Z",
     "iopub.status.busy": "2025-04-22T00:38:42.681582Z",
     "iopub.status.idle": "2025-04-22T00:38:42.686530Z",
     "shell.execute_reply": "2025-04-22T00:38:42.686058Z",
     "shell.execute_reply.started": "2025-04-22T00:38:42.681943Z"
    }
   },
   "outputs": [],
   "source": [
    "RE_EMOJI = re.compile(\"[\\U00010000-\\U0010ffff]\", flags=re.UNICODE)\n",
    "\n",
    "\n",
    "def clean_text(text):\n",
    "    \"\"\"General text cleaning. A bit tight but makes the content very clean.\"\"\"\n",
    "    text = \"\\n\" + text\n",
    "    text = RE_EMOJI.sub(r\"\", text)  # remove emojis\n",
    "    text = text.replace(\"’\", \"'\").lower()\n",
    "    text = text.replace('\"', \"\").lower()\n",
    "    text = re.sub(r\"\\[.+?\\]\", \" \", text)  # tags\n",
    "    text = re.sub(r\"\\n.+?\\:\", \" \", text)  # new line ends with :\n",
    "    text = re.sub(r\"\\n.+?\\：\", \" \", text)  # new line ends with :\n",
    "    text = re.sub(r\"\\n\\(.+?\\)\", \" \", text)  # new line with ()\n",
    "    text = re.sub(r\"[\\d]\", \" \", text)  # digits\n",
    "    text = re.sub(r\"▁\", \"\", text)  # special stuff\n",
    "    text = remove_speakers(text)\n",
    "    text = re.sub(r\"[^\\w\\'\\s]\", \" \", text)  # keep only the words\n",
    "    # text = re.sub(r\"[ \\t]+\", \" \", text)  # remove multiple whitespace\n",
    "    # text = re.sub(r\"\\n{2,}\", \"\\n\", text)  # Merge multiple newlines into single newline\n",
    "    text = normalize_whitespace(text)\n",
    "    return text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0d2555e3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:21.070547Z",
     "start_time": "2024-01-09T15:10:21.011397Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:52.955484Z",
     "iopub.status.busy": "2025-02-10T21:38:52.955198Z",
     "iopub.status.idle": "2025-02-10T21:38:52.995747Z",
     "shell.execute_reply": "2025-02-10T21:38:52.995218Z",
     "shell.execute_reply.started": "2025-02-10T21:38:52.955468Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1er Verse)\n",
      "C'est maintenant que j'mûris\n",
      "Que je m'aperçois dans quoi que j'vis\n",
      "J'vois que tout le monde paranoïe\n",
      "Savent même pas c'est quoi qu'y arrive\n",
      "Parfois je m'arrête\n",
      "En me disant c'est sur qu'un jour j'die, mais comment\n",
      "Personnellement, j'serais pas surpris\n",
      "Que ça serait une surprise\n",
      "Exemple, le temps\n",
      "La température fend\n",
      "La nature, elle nous haïs\n",
      "On a agit comme des p'tits mouks\n",
      "Fait que maintenant tout brise en les brisant\n",
      "L'échelle raccourcit\n",
      "J'vois qu' en haut, c'est pas loin\n",
      "Fuck, c'est tanant\n",
      "Y'a des choses que je me doute\n",
      "Quand je check le cadran\n",
      "Sur ma route, j'suis méfiant\n",
      "Tic tic tic\n",
      "J'avance en regardant\n",
      "J'suis tellement stressé\n",
      "Que mon tic, je le trouve stressant\n",
      "Quand j'me frotte le nez\n",
      "Depuis que j'suis enfant\n",
      "J'en ai enduré sérieusement\n",
      "On dit que le temps arrange les choses\n",
      "Mais le temps, je le trouve fucker moi\n",
      "(Refrain x2)\n",
      "J'vois la nature maltraitée\n",
      "Un autre ti-cul mal élevé\n",
      "Une autre prison bien remplie\n",
      "Un autre indice à cacher\n",
      "La vie, c'est un suspense\n",
      "Et moi, j'écris\n",
      "\n",
      "(2e Verse)\n",
      "Quand j'regarde ça, je m'inquiète pour demain\n",
      "Notre génération délire\n",
      "Nos enfants, dans quoi qui vont grandir hein?\n",
      "En tous cas, je les plaint\n",
      "Mais devant eux, je garde le sourire\n",
      "J'veux pas qu'ils prennent mon avion\n",
      "J'veux qu'ils sachent courir sans trébucher\n",
      "Mais c'est dur quand on regarde la société\n",
      "Dans n'importe quel quartier, y'a des mal élevés\n",
      "Y'a des filles que ça a douze ans\n",
      "Pis elles sont quasiment désabillées\n",
      "Le p'tit cul avec sa smoke plus grosse que lui\n",
      "Fréquente l'école tout crotté\n",
      "Déjà des jokes sur ma couleur\n",
      "Mais où est-ce qui es a pêché\n",
      "En plus d'être mal élevé, mal instruit\n",
      "Y sait même pas que j'suis un mélangé\n",
      "Éduquer un enfant de cette façon, c't'un péché\n",
      "Réalise bien qu'est-ce que lui en haut t'a donné\n",
      "Réalise bien qu'est-ce que lui en haut t'a donné\n",
      "Réalise bien qu'est-ce que la vie d'ici t'a donné\n",
      "Straight up\n",
      "\n",
      "\n",
      "(Refrain x2)\n",
      "J'vois la nature maltraitée\n",
      "Un autre ti-cul mal élevé\n",
      "Une autre prison bien remplie\n",
      "Un autre indice à cacher\n",
      "La vie, c'est un suspense\n",
      "Et moi, j'écris\n",
      "\n",
      "(3e Verse)\n",
      "Vu d'en haut de ma tour, j'vois que c'est pas beau\n",
      "Je m'aperçois que dehors, y fait pas chaud\n",
      "J'vois que tout le monde panique\n",
      "Veulent tous le plus gros morceau\n",
      "Détruire la nature ça c'est pas cool\n",
      "Aujourd'hui, elle est frustrée contre nous\n",
      "J'pense que l'être humain devrait commencer à prendre ça cool\n",
      "Parce que le temps qu'il faut qu'on rattrape\n",
      "J'vois qu'il s'écoule\n",
      "Faut évoluer, juste réalise dans quoi que t'avance\n",
      "C'est pas fini, c'est ta planète\n",
      "Human being\n",
      "\n",
      "(Refrain x2)\n",
      "J'vois la nature maltraitée\n",
      "Un autre ti-cul mal élevé\n",
      "Une autre prison bien remplie\n",
      "Un autre indice à cacher\n",
      "La vie, c'est un suspense\n",
      "Et moi, j'écris....\n",
      "-------\n",
      "c'est maintenant que j'mûris que je m'aperçois dans quoi que j'vis j'vois que tout le monde paranoïe savent même pas c'est quoi qu'y arrive parfois je m'arrête en me disant c'est sur qu'un jour j'die mais comment personnellement j'serais pas surpris que ça serait une surprise exemple le temps la température fend la nature elle nous haïs on a agit comme des p'tits mouks fait que maintenant tout brise en les brisant l'échelle raccourcit j'vois qu' en haut c'est pas loin fuck c'est tanant y'a des choses que je me doute quand je check le cadran sur ma route j'suis méfiant tic tic tic j'avance en regardant j'suis tellement stressé que mon tic je le trouve stressant quand j'me frotte le nez depuis que j'suis enfant j'en ai enduré sérieusement on dit que le temps arrange les choses mais le temps je le trouve fucker moi j'vois la nature maltraitée un autre ti cul mal élevé une autre prison bien remplie un autre indice à cacher la vie c'est un suspense et moi j'écris quand j'regarde ça je m'inquiète pour demain notre génération délire nos enfants dans quoi qui vont grandir hein en tous cas je les plaint mais devant eux je garde le sourire j'veux pas qu'ils prennent mon avion j'veux qu'ils sachent courir sans trébucher mais c'est dur quand on regarde la société dans n'importe quel quartier y'a des mal élevés y'a des filles que ça a douze ans pis elles sont quasiment désabillées le p'tit cul avec sa smoke plus grosse que lui fréquente l'école tout crotté déjà des jokes sur ma couleur mais où est ce qui es a pêché en plus d'être mal élevé mal instruit y sait même pas que j'suis un mélangé éduquer un enfant de cette façon c't'un péché réalise bien qu'est ce que lui en haut t'a donné réalise bien qu'est ce que lui en haut t'a donné réalise bien qu'est ce que la vie d'ici t'a donné straight up j'vois la nature maltraitée un autre ti cul mal élevé une autre prison bien remplie un autre indice à cacher la vie c'est un suspense et moi j'écris vu d'en haut de ma tour j'vois que c'est pas beau je m'aperçois que dehors y fait pas chaud j'vois que tout le monde panique veulent tous le plus gros morceau détruire la nature ça c'est pas cool aujourd'hui elle est frustrée contre nous j'pense que l'être humain devrait commencer à prendre ça cool parce que le temps qu'il faut qu'on rattrape j'vois qu'il s'écoule faut évoluer juste réalise dans quoi que t'avance c'est pas fini c'est ta planète human being j'vois la nature maltraitée un autre ti cul mal élevé une autre prison bien remplie un autre indice à cacher la vie c'est un suspense et moi j'écris\n"
     ]
    }
   ],
   "source": [
    "# Quality checks\n",
    "n_c = 0\n",
    "for m in metas:\n",
    "    if m[\"lang\"] == \"fr\":\n",
    "        n_c += 1\n",
    "        if n_c == 1:\n",
    "            text = m[\"lyrics\"]\n",
    "            print(text)\n",
    "            print(\"-------\")\n",
    "            print(clean_text(text))\n",
    "            break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e8b679e7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:21.167632Z",
     "start_time": "2024-01-09T15:10:21.072528Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:52.996756Z",
     "iopub.status.busy": "2025-02-10T21:38:52.996353Z",
     "iopub.status.idle": "2025-02-10T21:38:53.635566Z",
     "shell.execute_reply": "2025-02-10T21:38:53.634943Z",
     "shell.execute_reply.started": "2025-02-10T21:38:52.996740Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# TODO: swap to larger tokenizer\n",
    "import sentencepiece\n",
    "\n",
    "tokenizer = sentencepiece.SentencePieceProcessor()\n",
    "tokenizer.load(\"tokenizers/v5/tokenizer_spe_bpe_v20481/tokenizer.model\")\n",
    "\n",
    "# from hoot.model import Tokenizer\n",
    "# tokenizer = Tokenizer(filepath=\"/app/suno/data/dpo/models/tokenizer_60k.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2e51dedb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:53.636556Z",
     "iopub.status.busy": "2025-02-10T21:38:53.636286Z",
     "iopub.status.idle": "2025-02-10T21:38:53.682783Z",
     "shell.execute_reply": "2025-02-10T21:38:53.682208Z",
     "shell.execute_reply.started": "2025-02-10T21:38:53.636540Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(285,)\n",
      "whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 취할 것 같은 불빛이 화려한 밤에 누구보다도 자유로워 지기를 바래 아름다운 이 순간이 끝나기 전에 바람소리에 이 음악이 실리길 원해 whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh lets get it on tonight and set me free tonight 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time 두근거리는 느낌이 황홀한 밤에 푸른 바다에 달빛을 물들이길 바래 파도가 이 밤을 데려가기 전에 지금 이대로 시간이 멈추기를 원해 whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time whoa whoa whoa yeah oh whoa oh whoa oh whoa\n"
     ]
    }
   ],
   "source": [
    "import sentencepiece\n",
    "\n",
    "test_text = \"whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 취할 것 같은 불빛이 화려한 밤에 누구보다도 자유로워 지기를 바래 아름다운 이 순간이 끝나기 전에 바람소리에 이 음악이 실리길 원해 whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh lets get it on tonight and set me free tonight 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time 두근거리는 느낌이 황홀한 밤에 푸른 바다에 달빛을 물들이길 바래 파도가 이 밤을 데려가기 전에 지금 이대로 시간이 멈추기를 원해 whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time whoa oh oh whoa oh oh whoa oh oh oh oh oh oh whoa oh oh whoa oh oh whoa oh oh oh oh oh oh 이 순간 즐겨봐 너와 나 소리 높여 lets groove it party time whoa whoa whoa yeah oh whoa oh whoa oh whoa\"\n",
    "\n",
    "print(np.array(tokenizer.encode(test_text)).shape)\n",
    "print(tokenizer.decode(tokenizer.encode(test_text)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "feacb5f1",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T15:10:22.487284Z",
     "start_time": "2024-01-09T15:10:21.169512Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-10T21:38:53.683648Z",
     "iopub.status.busy": "2025-02-10T21:38:53.683391Z",
     "iopub.status.idle": "2025-02-10T21:38:57.588000Z",
     "shell.execute_reply": "2025-02-10T21:38:57.587208Z",
     "shell.execute_reply.started": "2025-02-10T21:38:53.683632Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4751783 4665755\n"
     ]
    }
   ],
   "source": [
    "print(len(subset_meta), len(set(m[\"id\"] for m in subset_meta)))\n",
    "random.shuffle(subset_meta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "3a3246ca",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:53.367719Z",
     "start_time": "2024-01-09T15:10:22.489702Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:39:06.145050Z",
     "iopub.status.busy": "2025-04-22T00:39:06.144645Z",
     "iopub.status.idle": "2025-04-22T00:39:06.168413Z",
     "shell.execute_reply": "2025-04-22T00:39:06.167818Z",
     "shell.execute_reply.started": "2025-04-22T00:39:06.145031Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'subset_meta' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[28], line 9\u001b[0m\n\u001b[1;32m      7\u001b[0m n_lang_max_cut \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m5_000_000\u001b[39m  \u001b[38;5;66;03m# 10k songs :D, 2_000_000 is max\u001b[39;00m\n\u001b[1;32m      8\u001b[0m bad_meta_ids \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m----> 9\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m meta \u001b[38;5;129;01min\u001b[39;00m tqdm\u001b[38;5;241m.\u001b[39mtqdm(\u001b[43msubset_meta\u001b[49m):\n\u001b[1;32m     10\u001b[0m     output_path \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(\n\u001b[1;32m     11\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/app/suno/data/hoot/audios/genius/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmeta[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124moriginal_id\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.mp3\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     12\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m meta[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdataset\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenius\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     13\u001b[0m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/app/suno/data/audios/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmeta[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdataset\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmeta[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mid\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.mp3\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     14\u001b[0m     )\n\u001b[1;32m     15\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mexists(output_path):\n",
      "\u001b[0;31mNameError\u001b[0m: name 'subset_meta' is not defined"
     ]
    }
   ],
   "source": [
    "total_infos = []\n",
    "n_text_too_short = 0\n",
    "n_text_too_long = 0\n",
    "n_audio_too_long = 0\n",
    "n_lang = collections.defaultdict(int)\n",
    "n_repeat_ratio_too_high = 0\n",
    "n_lang_max_cut = 5_000_000  # 10k songs :D, 2_000_000 is max\n",
    "bad_meta_ids = []\n",
    "for meta in tqdm.tqdm(subset_meta):\n",
    "    output_path = os.path.join(\n",
    "        f\"/app/suno/data/hoot/audios/genius/{meta['original_id']}.mp3\"\n",
    "        if meta[\"dataset\"] == \"genius\"\n",
    "        else f\"/app/suno/data/audios/{meta['dataset']}/{meta['id']}.mp3\"\n",
    "    )\n",
    "    if not os.path.exists(output_path):\n",
    "        continue\n",
    "    # output_path = downloaded_ids_to_info[meta[\"id\"]][\"filepath\"]\n",
    "    if (\n",
    "        meta[\"duration_s\"] > 400\n",
    "    ):  # this cut is mainly for batching purposes...X.x, but...we probably shouldn't have this.\n",
    "        n_audio_too_long += 1\n",
    "        continue\n",
    "    n_lang[meta[\"lang\"]] += 1\n",
    "    # if n_lang[meta[\"lang\"]] > n_lang_max_cut:\n",
    "    #     continue\n",
    "    cleaned_text = clean_text(meta[\"lyrics\"])\n",
    "    # cleaned_text = meta[\"lyrics\"].lower() # clean_text(meta[\"lyrics\"])\n",
    "    #     cleaned_tokens = tokenizer.encode(cleaned_text)\n",
    "    #     decoded_tokens = tokenizer.decode(cleaned_tokens)\n",
    "    #     if decoded_tokens != cleaned_text:\n",
    "    #         print(cleaned_text)\n",
    "    #         print(decoded_tokens)\n",
    "    if len(cleaned_text) < 20:\n",
    "        n_text_too_short += 1\n",
    "        continue\n",
    "    # check the high freq token frequency\n",
    "    encoded_array = np.array(tokenizer.encode(cleaned_text))\n",
    "    if len(encoded_array) > meta[\"duration_s\"] * 12:\n",
    "        n_text_too_long += 1\n",
    "        continue\n",
    "    repeat_ratio = max(np.bincount(encoded_array)) / (encoded_array.shape[0] + 1)\n",
    "    if repeat_ratio > 0.3:\n",
    "        n_repeat_ratio_too_high += 1\n",
    "        bad_meta_ids.append(meta[\"id\"])\n",
    "        continue\n",
    "    total_infos.append(\n",
    "        {\n",
    "            \"audio_filepath\": output_path,\n",
    "            \"duration\": meta[\"duration_s\"],\n",
    "            \"text\": cleaned_text,\n",
    "            \"lyrics\": meta[\"lyrics\"],\n",
    "            \"lang\": meta[\"lang\"],\n",
    "            \"id\": meta[\"id\"],\n",
    "            \"dataset\": meta[\"dataset\"],\n",
    "            # \"genius_views\": meta.get(\"genius_views\", 0),\n",
    "            # \"youtube_views\": meta.get(\"youtube_views\", 0),\n",
    "        }\n",
    "    )\n",
    "    if not os.path.exists(output_path):\n",
    "        # print(\"WTF\", output_path)\n",
    "        continue\n",
    "#     audio = Audio.from_s3(meta[\"audio_filepath\"])\n",
    "#     audio = audio.convert(16_000, audio.byte_width, n_channels=1)\n",
    "#     audio.to_wav(output_path)\n",
    "print(\n",
    "    f\"total {len(total_infos)}, too long: {n_audio_too_long}, text too short: {n_text_too_short}, text too long: {n_text_too_long}, text bad: {n_repeat_ratio_too_high}\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "618075a0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:54.930054Z",
     "start_time": "2024-01-09T16:37:53.368988Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:00.833324Z",
     "iopub.status.busy": "2025-02-11T03:40:00.832866Z",
     "iopub.status.idle": "2025-02-11T03:40:05.275941Z",
     "shell.execute_reply": "2025-02-11T03:40:05.275345Z",
     "shell.execute_reply.started": "2025-02-11T03:40:00.833303Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total duration khr 276.7099622222222 60 400 20 14294\n"
     ]
    }
   ],
   "source": [
    "print(\n",
    "    \"total duration khr\",\n",
    "    sum(m[\"duration\"] for m in total_infos) / 3600000,\n",
    "    min(m[\"duration\"] for m in total_infos),\n",
    "    max(m[\"duration\"] for m in total_infos),\n",
    "    min(len(m[\"text\"]) for m in total_infos),\n",
    "    max(len(m[\"text\"]) for m in total_infos),\n",
    ")\n",
    "# 29.15879888888889 120 100 2879\n",
    "# cut on durations 400: total duration khr 88.80962305555556 60 480 100 5616\n",
    "# cut on 240: total duration khr 54.709809444444446 60 240 100 2880"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "76dcc2f9-777f-476e-b190-fddced599117",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:13.145074Z",
     "iopub.status.busy": "2025-02-11T03:40:13.144659Z",
     "iopub.status.idle": "2025-02-11T03:40:13.147612Z",
     "shell.execute_reply": "2025-02-11T03:40:13.147188Z",
     "shell.execute_reply.started": "2025-02-11T03:40:13.145054Z"
    }
   },
   "outputs": [],
   "source": [
    "# exist_info = []\n",
    "# for test_input in test_info:\n",
    "#     if os.path.exists(test_input[\"audio_filepath\"]):\n",
    "#         exist_info.append(test_input)\n",
    "# print(len(info), len(exist_info))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "38f9f3d9-f5ac-4ad9-be01-b34a14c12a81",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:39:41.341889Z",
     "iopub.status.busy": "2025-04-22T00:39:41.341179Z",
     "iopub.status.idle": "2025-04-22T00:51:30.975764Z",
     "shell.execute_reply": "2025-04-22T00:51:30.975206Z",
     "shell.execute_reply.started": "2025-04-22T00:39:41.341869Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████████████████████████████████████████████████████████████████████████████████████████████| 4751783/4751783 [11:49<00:00, 6696.16it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 4683910, too long: 65981, text too short: 1892, text too long: 0, text bad: 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "total_infos = []\n",
    "n_text_too_short = 0\n",
    "n_text_too_long = 0\n",
    "n_audio_too_long = 0\n",
    "n_lang = collections.defaultdict(int)\n",
    "n_repeat_ratio_too_high = 0\n",
    "n_lang_max_cut = 5_000_000  # 10k songs :D, 2_000_000 is max\n",
    "bad_meta_ids = []\n",
    "for meta in tqdm.tqdm(metas):\n",
    "    output_path = os.path.join(\n",
    "        f\"/app/suno/data/hoot/audios/genius/{meta['original_id']}.mp3\"\n",
    "        if meta[\"dataset\"] == \"genius\"\n",
    "        else f\"/app/suno/data/audios/{meta['dataset']}/{meta['id']}.mp3\"\n",
    "    )\n",
    "    if (\n",
    "        meta[\"duration_s\"] > 400\n",
    "    ):  # this cut is mainly for batching purposes...X.x, but...we probably shouldn't have this.\n",
    "        n_audio_too_long += 1\n",
    "        continue\n",
    "    n_lang[meta[\"lang\"]] += 1\n",
    "    # if n_lang[meta[\"lang\"]] > n_lang_max_cut:\n",
    "    #     continue\n",
    "    cleaned_text = clean_text(meta[\"lyrics\"])\n",
    "    # cleaned_text = meta[\"lyrics\"].lower() # clean_text(meta[\"lyrics\"])\n",
    "    #     cleaned_tokens = tokenizer.encode(cleaned_text)\n",
    "    #     decoded_tokens = tokenizer.decode(cleaned_tokens)\n",
    "    #     if decoded_tokens != cleaned_text:\n",
    "    #         print(cleaned_text)\n",
    "    #         print(decoded_tokens)\n",
    "    if len(cleaned_text) < 20:\n",
    "        n_text_too_short += 1\n",
    "        continue\n",
    "    # check the high freq token frequency\n",
    "    total_infos.append(\n",
    "        {\n",
    "            \"audio_filepath\": output_path,\n",
    "            \"duration\": meta[\"duration_s\"],\n",
    "            \"text\": cleaned_text,\n",
    "            \"lyrics\": meta[\"lyrics\"],\n",
    "            \"lang\": meta[\"lang\"],\n",
    "            \"id\": meta[\"id\"],\n",
    "            \"dataset\": meta[\"dataset\"],\n",
    "            # \"genius_views\": meta.get(\"genius_views\", 0),\n",
    "            # \"youtube_views\": meta.get(\"youtube_views\", 0),\n",
    "        }\n",
    "    )\n",
    "print(\n",
    "    f\"total {len(total_infos)}, too long: {n_audio_too_long}, text too short: {n_text_too_short}, text too long: {n_text_too_long}, text bad: {n_repeat_ratio_too_high}\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "d8eb67a9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:55.757800Z",
     "start_time": "2024-01-09T16:37:54.931303Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:51:30.976706Z",
     "iopub.status.busy": "2025-04-22T00:51:30.976550Z",
     "iopub.status.idle": "2025-04-22T00:51:31.029657Z",
     "shell.execute_reply": "2025-04-22T00:51:31.029191Z",
     "shell.execute_reply.started": "2025-04-22T00:51:30.976691Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4683910 0\n"
     ]
    }
   ],
   "source": [
    "# cutoff = -2000\n",
    "# random.shuffle(info)\n",
    "# train_info = info[:cutoff]\n",
    "# test_info = info[cutoff:]\n",
    "# print(len(train_info), len(test_info))\n",
    "# # 545838 1000\n",
    "train_info = total_infos.copy()\n",
    "test_info = []\n",
    "print(len(train_info), len(test_info))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "72bc9539",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:14.716658Z",
     "iopub.status.busy": "2025-02-11T03:40:14.716500Z",
     "iopub.status.idle": "2025-02-11T03:40:14.718743Z",
     "shell.execute_reply": "2025-02-11T03:40:14.718351Z",
     "shell.execute_reply.started": "2025-02-11T03:40:14.716643Z"
    }
   },
   "outputs": [],
   "source": [
    "# BREAK"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a48b2d77",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:55.761119Z",
     "start_time": "2024-01-09T16:37:55.759035Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:15.256599Z",
     "iopub.status.busy": "2025-02-11T03:40:15.255881Z",
     "iopub.status.idle": "2025-02-11T03:40:15.263995Z",
     "shell.execute_reply": "2025-02-11T03:40:15.263216Z",
     "shell.execute_reply.started": "2025-02-11T03:40:15.256549Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/all_train_manifest_fast.json\", \"w\") as fp:\n",
    "#     # for l in train_info[:80]:\n",
    "#     for l in train_info[:80]:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')\n",
    "# with open(\"/home/tony/Data/Hoot/all_test_manifest_fast.json\", \"w\") as fp:\n",
    "#     for l in test_info[:8]:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "4a7003ff",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:55.836785Z",
     "start_time": "2024-01-09T16:37:55.762070Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:15.504921Z",
     "iopub.status.busy": "2025-02-11T03:40:15.504399Z",
     "iopub.status.idle": "2025-02-11T03:40:15.507083Z",
     "shell.execute_reply": "2025-02-11T03:40:15.506665Z",
     "shell.execute_reply.started": "2025-02-11T03:40:15.504903Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/multi_all_104khr_filtered_train_manifest.json\", \"w\") as fp:\n",
    "#     for l in train_info:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')\n",
    "# with open(\"/home/tony/Data/Hoot/multi_all_104khr_filtered_test_manifest.json\", \"w\") as fp:\n",
    "#     for l in test_info:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "506b6b20",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:55.891610Z",
     "start_time": "2024-01-09T16:37:55.838219Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:15.629069Z",
     "iopub.status.busy": "2025-02-11T03:40:15.628682Z",
     "iopub.status.idle": "2025-02-11T03:40:15.631048Z",
     "shell.execute_reply": "2025-02-11T03:40:15.630592Z",
     "shell.execute_reply.started": "2025-02-11T03:40:15.629053Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(DataStoreObject(manifest).get(), 'r') as in_reader:\n",
    "#     for line in in_reader:\n",
    "#         item = json.loads(line)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5907d689",
   "metadata": {},
   "source": [
    "# Train the tokenizer"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a36ab23",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- 0.998 has vocab size of 780\n",
    "- 0.9995 has vocab size of 1936\n",
    "- 0.9996 has vocab of 2176\n",
    "- 0.9999 has vocab of 3878\n",
    "- 1.0 has vocab of 12402\n",
    "\n",
    "new data\n",
    "- 99.999% Alphabet size=8681\n",
    "- 100% Alphabet size=15105\n",
    "\n",
    "------------------------\n",
    "   ------------------------\n",
    " python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --manifest=\"/home/tony/Data/Hoot/metas.json\" \\\n",
    "  --data_root=\"./tokenizers/full/\" \\\n",
    "  --vocab_size=10240 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=1.0 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --log\n",
    "  \n",
    "   ------------------------\n",
    " python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --manifest=\"/home/tony/Data/Hoot/multi_all_104khr_filtered_train_manifest.json\" \\\n",
    "  --data_root=\"./tokenizers/v3/\" \\\n",
    "  --vocab_size=10241 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=1.0 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --log\n",
    "\n",
    "     ------------------------\n",
    " python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --manifest=\"/home/tony/Data/Hoot/genius_metas.json,/home/tony/Data/Hoot/deezer_metas.json,/home/tony/Data/Hoot/discogs_metas.json\" \\\n",
    "  --data_root=\"./tokenizers/v5/\" \\\n",
    "  --vocab_size=20481 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=0.99999 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --log\n",
    "\n",
    "python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --manifest=\"/home/tony/Data/Hoot/genius_metas.json,/home/tony/Data/Hoot/deezer_metas.json,/home/tony/Data/Hoot/discogs_metas.json\" \\\n",
    "  --data_root=\"./tokenizers/v5/\" \\\n",
    "  --vocab_size=20484 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=1.0 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --log\n",
    "\n",
    "trainer_interface.cc(539) LOG(INFO) all chars count=15479707103\n",
    "trainer_interface.cc(550) LOG(INFO) Done: 100% characters are covered\n",
    "trainer_interface.cc(560) LOG(INFO) Alphabet size=16079\n",
    "trainer_interface.cc(561) LOG(INFO) Final character coverage=1\n",
    "\n",
    "python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --data_file=\"/home/tony/Work/tony/FineTuning_chirp_v4/tmp/tokenizer_train_clean.txt\" \\\n",
    "  --data_root=\"./tokenizers/v5/\" \\\n",
    "  --vocab_size=20484 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=1.0 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --log\n",
    "\n",
    "trainer_interface.cc(539) LOG(INFO) all chars count=15479707103\n",
    "trainer_interface.cc(550) LOG(INFO) Done: 100% characters are covered.\n",
    "trainer_interface.cc(560) LOG(INFO) Alphabet size=16570\n",
    "trainer_interface.cc(561) LOG(INFO) Final character coverage=1\n",
    "\n",
    "python ./scripts/process_asr_text_tokenizer.py \\\n",
    "  --data_file=\"/home/tony/Work/tony/FineTuning_chirp_v4/tmp/tokenizer_train_clean.txt\" \\\n",
    "  --data_root=\"./tokenizers/v5/\" \\\n",
    "  --vocab_size=20488 \\\n",
    "  --tokenizer=\"spe\" \\\n",
    "  --spe_character_coverage=1.0 \\\n",
    "  --spe_type=\"bpe\" \\\n",
    "  --no_lower_case \\\n",
    "  --log"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d966633",
   "metadata": {},
   "source": [
    "# DEBUG"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "353d4d0f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.239480Z",
     "start_time": "2024-01-09T16:37:56.184175Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:16.985249Z",
     "iopub.status.busy": "2025-02-11T03:40:16.984190Z",
     "iopub.status.idle": "2025-02-11T03:40:16.994763Z",
     "shell.execute_reply": "2025-02-11T03:40:16.992908Z",
     "shell.execute_reply.started": "2025-02-11T03:40:16.985161Z"
    }
   },
   "outputs": [],
   "source": [
    "# x = []\n",
    "# with open(\"/home/tony/Data/Hoot/all_train_manifest.json\", \"r\") as fp:\n",
    "#      for l in fp:\n",
    "#         x.append(json.loads(l))\n",
    "\n",
    "# bad_indices = []\n",
    "# for i, meta in tqdm.tqdm(enumerate(x)):\n",
    "#     encoded_array = np.array(tokenizer.encode(meta[\"text\"]))\n",
    "#     repeat_ratio = max(np.bincount(encoded_array)) / (encoded_array.shape[0] + 1)\n",
    "#     if repeat_ratio > 0.3:\n",
    "#         # print(repeat_ratio, meta)\n",
    "#         bad_indices.append(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "e5f54770",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.293353Z",
     "start_time": "2024-01-09T16:37:56.240396Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:17.336607Z",
     "iopub.status.busy": "2025-02-11T03:40:17.336154Z",
     "iopub.status.idle": "2025-02-11T03:40:17.338947Z",
     "shell.execute_reply": "2025-02-11T03:40:17.338467Z",
     "shell.execute_reply.started": "2025-02-11T03:40:17.336590Z"
    }
   },
   "outputs": [],
   "source": [
    "# len(bad_indices)\n",
    "\n",
    "# bad_ids = [\n",
    "#     36004, 91329, 772492\n",
    "# ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "f65a307d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.365226Z",
     "start_time": "2024-01-09T16:37:56.294287Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:17.729672Z",
     "iopub.status.busy": "2025-02-11T03:40:17.729338Z",
     "iopub.status.idle": "2025-02-11T03:40:17.732185Z",
     "shell.execute_reply": "2025-02-11T03:40:17.731813Z",
     "shell.execute_reply.started": "2025-02-11T03:40:17.729654Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/all_train_manifest_debug.json\", \"w\") as fp:\n",
    "#     # for l in train_info[:80]:\n",
    "#     for l in selected:\n",
    "#         json.dump(x[l], fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "9c374d06",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.420690Z",
     "start_time": "2024-01-09T16:37:56.366689Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:18.333288Z",
     "iopub.status.busy": "2025-02-11T03:40:18.332897Z",
     "iopub.status.idle": "2025-02-11T03:40:18.335962Z",
     "shell.execute_reply": "2025-02-11T03:40:18.335434Z",
     "shell.execute_reply.started": "2025-02-11T03:40:18.333270Z"
    }
   },
   "outputs": [],
   "source": [
    "# for bad_id in bad_ids:\n",
    "#     print(x[bad_id])\n",
    "\n",
    "# test_audio = Audio.from_file('/app/suno/data/hoot/2I8_OV4DtCs.wav')\n",
    "# test_audio.play(compress=False)\n",
    "\n",
    "# for meta in base_metas:\n",
    "#     if meta[\"original_id\"] == \"JpkwJW92UcY\":\n",
    "#         print(meta)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7f8985c",
   "metadata": {},
   "source": [
    "# Load the hooted output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "a7be6e73",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.505275Z",
     "start_time": "2024-01-09T16:37:56.421982Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:19.173423Z",
     "iopub.status.busy": "2025-02-11T03:40:19.173034Z",
     "iopub.status.idle": "2025-02-11T03:40:19.176126Z",
     "shell.execute_reply": "2025-02-11T03:40:19.175693Z",
     "shell.execute_reply.started": "2025-02-11T03:40:19.173404Z"
    }
   },
   "outputs": [],
   "source": [
    "# total_infos = dict()\n",
    "# for i in tqdm.tqdm(range(0, 1836168, 100)):\n",
    "#     if not os.path.exists(f\"/home/tony/Data/Hoot/alignments/outputs/batch_{i}.json\"):\n",
    "#         # print(\"Missing,\", i)\n",
    "#         continue\n",
    "#     try:\n",
    "#         with open(f\"/home/tony/Data/Hoot/alignments/outputs/batch_{i}.json\", \"r\") as fp:\n",
    "#             infos = json.load(fp)\n",
    "#         for x_info in infos:\n",
    "#             if x_info[\"id\"] in total_infos:\n",
    "#                 break\n",
    "#             total_infos[x_info[\"id\"]] = x_info[\"cer_val\"]\n",
    "#     except:\n",
    "#         # print(\"WTF,\", i)\n",
    "#         pass\n",
    "\n",
    "# plt.hist(total_infos.values(), bins=np.linspace(0, 1, 50))\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "552c1c73",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.570374Z",
     "start_time": "2024-01-09T16:37:56.506567Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:19.698553Z",
     "iopub.status.busy": "2025-02-11T03:40:19.698124Z",
     "iopub.status.idle": "2025-02-11T03:40:19.701510Z",
     "shell.execute_reply": "2025-02-11T03:40:19.700963Z",
     "shell.execute_reply.started": "2025-02-11T03:40:19.698534Z"
    }
   },
   "outputs": [],
   "source": [
    "# high_cer_infos = {k:v for k, v in total_infos.items() if v < 0.4}\n",
    "# print(len(high_cer_infos))\n",
    "\n",
    "# high_cer_train_info = []\n",
    "# for info in train_info:\n",
    "#     if info[\"id\"] in high_cer_infos and info[\"duration\"] < 240:\n",
    "#         high_cer_train_info.append(info)\n",
    "# print(len(high_cer_train_info))\n",
    "\n",
    "# print(\n",
    "#     \"total duration khr\", sum(m[\"duration\"] for m in high_cer_train_info) / 3600000,\n",
    "#     min(m[\"duration\"] for m in high_cer_train_info),\n",
    "#     max(m[\"duration\"] for m in high_cer_train_info),\n",
    "#     min(len(m[\"text\"]) for m in high_cer_train_info),\n",
    "#     max(len(m[\"text\"]) for m in high_cer_train_info),\n",
    "# )\n",
    "\n",
    "# print(Counter(m[\"lang\"] for m in high_cer_train_info))\n",
    "\n",
    "# cutoff = -2000\n",
    "# random.shuffle(high_cer_train_info)\n",
    "# high_cer_train_info, high_cer_test_info = high_cer_train_info[:cutoff], high_cer_train_info[cutoff:]\n",
    "# print(len(high_cer_train_info), len(high_cer_test_info))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "417c0eb3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-09T16:37:56.651676Z",
     "start_time": "2024-01-09T16:37:56.571763Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-11T03:40:19.861247Z",
     "iopub.status.busy": "2025-02-11T03:40:19.860939Z",
     "iopub.status.idle": "2025-02-11T03:40:19.863307Z",
     "shell.execute_reply": "2025-02-11T03:40:19.862910Z",
     "shell.execute_reply.started": "2025-02-11T03:40:19.861230Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/multi_large_vocab_cer_04_train.json\", \"w\") as fp:\n",
    "#     for l in high_cer_train_info:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')\n",
    "# with open(\"/home/tony/Data/Hoot/multi_large_vocab_cer_04_test.json\", \"w\") as fp:\n",
    "#     for l in high_cer_test_info:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1642e3b5",
   "metadata": {},
   "source": [
    "# 2nd round of hoot data prep setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "52f2a9a1",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:43:46.229977Z",
     "start_time": "2024-01-18T02:43:05.476371Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:16.059149Z",
     "iopub.status.busy": "2025-04-21T23:48:16.058826Z",
     "iopub.status.idle": "2025-04-21T23:48:17.260394Z",
     "shell.execute_reply": "2025-04-21T23:48:17.259700Z",
     "shell.execute_reply.started": "2025-04-21T23:48:16.059131Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/genius_metas.json\", \"r\") as fp:\n",
    "#     metas = json.load(fp)\n",
    "metas_map = {m[\"id\"]: m for m in metas}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "274e39d7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:57:19.260628Z",
     "start_time": "2024-01-18T02:43:49.821152Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-21T23:48:17.261321Z",
     "iopub.status.busy": "2025-04-21T23:48:17.261163Z",
     "iopub.status.idle": "2025-04-22T00:32:45.154621Z",
     "shell.execute_reply": "2025-04-22T00:32:45.154057Z",
     "shell.execute_reply.started": "2025-04-21T23:48:17.261306Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 18353/18353 [19:24<00:00, 15.77it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7618/7618 [06:53<00:00, 18.42it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WTF, 761700\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 64%|████████████████████████████████████████████████████████████████████▊                                      | 13858/21550 [11:40<18:22,  6.98it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WTF, 1385600\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 77%|██████████████████████████████████████████████████████████████████████████████████▏                        | 16547/21550 [13:59<03:16, 25.47it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WTF, 1654400\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 21550/21550 [18:09<00:00, 19.77it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WTF, 2154900\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "from collections import defaultdict\n",
    "\n",
    "total_infos_2 = dict()\n",
    "lang_cers = defaultdict(list)\n",
    "\n",
    "\n",
    "def process_and_merge_alignments(\n",
    "    total_infos_2, metas_map, lang_cers, dataset, last_idx\n",
    "):\n",
    "    for i in tqdm.tqdm(range(0, last_idx, 100)):\n",
    "        try:\n",
    "            with open(\n",
    "                f\"/app/suno/data/hoot/alignments/{dataset}/batch_{i}.json\", \"r\"\n",
    "            ) as fp:\n",
    "                infos = json.load(fp)\n",
    "            for x_info in infos:\n",
    "                if x_info[\"id\"] in total_infos_2:\n",
    "                    break\n",
    "                if x_info[\"id\"] not in metas_map:\n",
    "                    continue\n",
    "                total_infos_2[x_info[\"id\"]] = x_info[\"cer_val\"]\n",
    "                lang_cers[metas_map[x_info[\"id\"]][\"lang\"]].append(x_info[\"cer_val\"])\n",
    "        except:\n",
    "            print(\"WTF,\", i)\n",
    "    return total_infos_2, lang_cers\n",
    "\n",
    "\n",
    "total_infos_2, lang_cers = process_and_merge_alignments(\n",
    "    total_infos_2, metas_map, lang_cers, \"genius_v5_fix\", 1835300\n",
    ")\n",
    "total_infos_2, lang_cers = process_and_merge_alignments(\n",
    "    total_infos_2, metas_map, lang_cers, \"deezer_v5_fix\", 761800\n",
    ")\n",
    "total_infos_2, lang_cers = process_and_merge_alignments(\n",
    "    total_infos_2, metas_map, lang_cers, \"discogs_v5_fix\", 2155000\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "0f22ea07-f456-4433-b470-66d1109551a0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:32:45.156212Z",
     "iopub.status.busy": "2025-04-22T00:32:45.156042Z",
     "iopub.status.idle": "2025-04-22T00:32:45.601514Z",
     "shell.execute_reply": "2025-04-22T00:32:45.600957Z",
     "shell.execute_reply.started": "2025-04-22T00:32:45.156195Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': 'BPkMuliGqJQ', 'lyrics': \"Come all you pretty women with your hair a hanging down\\nOpen up your windows 'cause the Candyman's in town\\nCome on boys and gamble, roll those laughing bones\\nSeven come eleven, boys I'll take your money home\\n\\nLook out, look out, the Candyman\\nHere he comes and he's gone again\\nPretty lady ain't got no friend\\nTill the Candyman comes around again\\n\\nI come in from Memphis where I, I learned to talk the jive\\nWhen I get back to Memphis, be one less man alive\\nGood morning Mr. Benson, I see you're doing well\\nIf I had me a shotgun, I'd blow you straight to Hell\\n\\nLook out, look out, the Candyman\\nHere he comes and he's gone again\\nPretty lady ain't got no friend\\nTill the Candyman comes around again\\n\\nOoh, ooh, ooh\\nOoh, ooh, ooh\\n\\nCome on boys and wager, if you have got the mind\\nIf you've got a dollar boys, lay it on the line\\nHand me my old guitar, pass the whiskey 'round\\nWon't you tell everybody you meet that the Candyman's in town, 'own\\n\\nLook out, look out, the Candyman\\nHere he comes and he's gone again\\nPretty lady ain't got no friend\\nTill the Candyman comes around again\\n\\nLook out, look out, the Candyman\\nHere he comes and he's gone again\\nLook out, look out, the Candyman\", 'duration_s': 374, 'lang': 'en', 'audio_filepath': 's3://suno-data/shared/nfdg/BPkMuliGqJQ/BPkMuliGqJQ/audio.webm', 'dataset': 'discogs'}\n"
     ]
    }
   ],
   "source": [
    "for meta_id, meta_value in metas_map.items():\n",
    "    if meta_id not in total_infos_2 and meta_value[\"dataset\"] == \"discogs\" and meta_value[\"lang\"] == \"en\":\n",
    "        print(meta_value)\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "033dc016",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:57:19.317468Z",
     "start_time": "2024-01-18T02:57:19.266816Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:32:45.602229Z",
     "iopub.status.busy": "2025-04-22T00:32:45.602084Z",
     "iopub.status.idle": "2025-04-22T00:32:45.604916Z",
     "shell.execute_reply": "2025-04-22T00:32:45.604493Z",
     "shell.execute_reply.started": "2025-04-22T00:32:45.602214Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total_infos_2, lang_cers 3101271 199\n"
     ]
    }
   ],
   "source": [
    "print(\"total_infos_2, lang_cers\", len(total_infos_2), len(lang_cers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ca6fcca0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T02:57:19.825960Z",
     "start_time": "2024-01-18T02:57:19.318687Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:32:45.605488Z",
     "iopub.status.busy": "2025-04-22T00:32:45.605358Z",
     "iopub.status.idle": "2025-04-22T00:32:46.302127Z",
     "shell.execute_reply": "2025-04-22T00:32:46.301557Z",
     "shell.execute_reply.started": "2025-04-22T00:32:45.605475Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lang n_songs median cer\n",
      "en 1896824 0.204\n",
      "es 241994 0.164\n",
      "pt 130654 0.196\n",
      "fr 123694 0.251\n",
      "de 101101 0.205\n",
      "it 79151 0.15\n",
      "ru 77166 0.22\n",
      "pl 63700 0.201\n",
      "ko 47424 0.277\n",
      "ja 46191 0.35\n",
      "tr 40277 0.216\n",
      "nl 16531 0.288\n",
      "ar 14981 0.358\n",
      "id 14411 0.256\n",
      "hi 12288 0.356\n",
      "iw 11926 0.3\n",
      "el 11349 0.384\n",
      "sv 10916 0.31\n",
      "ro 10550 0.271\n",
      "da 9459 0.343\n",
      "fi 8397 0.29\n",
      "zh 8057 0.367\n",
      "sr 8026 0.227\n",
      "tl 7966 0.287\n",
      "cs 7420 0.252\n",
      "hr 7147 0.221\n",
      "vi 7115 0.389\n",
      "no 6376 0.353\n",
      "hu 5703 0.334\n",
      "pa 5265 0.333\n",
      "th 4541 0.443\n",
      "fa 4503 0.296\n",
      "romanization 4275 0.691\n",
      "az 3961 0.283\n",
      "zh-Hant 3640 0.363\n",
      "sk 3628 0.285\n",
      "uk 3130 0.326\n",
      "bs 3036 0.238\n",
      "bg 2264 0.329\n",
      "sq 2030 0.42\n",
      "ca 1935 0.336\n",
      "af 1908 0.316\n",
      "et 1826 0.493\n",
      "ms 1775 0.317\n",
      "he 1735 0.293\n",
      "lv 1511 0.416\n",
      "lt 1338 0.452\n",
      "bn 1307 0.282\n",
      "sl 1209 0.386\n",
      "sw 1044 0.446\n",
      "eu 1042 0.512\n",
      "is 911 0.575\n",
      "ne 866 0.394\n",
      "la 754 0.863\n",
      "ta 727 0.457\n",
      "mr 628 0.417\n",
      "mk 626 0.416\n",
      "gl 599 0.427\n",
      "zu 594 0.606\n",
      "ht 545 0.515\n",
      "co 494 0.468\n",
      "si 445 0.984\n",
      "eo 437 0.56\n",
      "sco 426 0.344\n",
      "am 362 0.558\n",
      "ku 350 0.679\n",
      "cy 328 0.753\n",
      "te 328 1.0\n",
      "ka 311 0.612\n",
      "xh 294 0.637\n",
      "mn 258 0.685\n",
      "hy 257 0.615\n",
      "ceb 244 0.41\n",
      "als 230 0.575\n",
      "war 228 0.638\n",
      "ml 226 1.0\n",
      "ga 221 0.84\n",
      "uz 217 0.633\n",
      "nn 202 0.383\n",
      "my 196 0.984\n",
      "kk 196 0.615\n",
      "ln 186 0.63\n",
      "yo 177 0.586\n",
      "jv 176 0.598\n",
      "sn 161 0.554\n",
      "su 158 0.617\n",
      "arz 158 0.416\n",
      "rw 156 0.57\n",
      "km 153 0.984\n",
      "ur 146 0.97\n",
      "be 130 0.51\n",
      "sa 126 0.765\n",
      "gd 114 0.87\n",
      "lb 114 0.567\n",
      "wo 112 0.742\n",
      "kn 102 1.0\n",
      "mg 101 0.685\n",
      "br 99 0.811\n",
      "jw 98 0.526\n",
      "st 94 0.652\n",
      "ak 91 0.626\n",
      "sh 90 0.408\n",
      "or 84 1.0\n",
      "mi 82 0.662\n",
      "bh 76 0.522\n",
      "rm 75 0.626\n",
      "oc 72 0.644\n",
      "yi 72 0.828\n",
      "ky 71 0.529\n",
      "fo 70 0.615\n",
      "lg 69 0.583\n",
      "so 68 0.786\n",
      "aa 56 0.814\n",
      "tt 56 0.784\n",
      "as 56 0.458\n",
      "tk 55 0.649\n",
      "ia 55 0.458\n",
      "gu 53 1.0\n",
      "ig 53 0.687\n",
      "sm 51 0.602\n",
      "tn 51 0.637\n",
      "mt 50 0.832\n",
      "qu 49 0.608\n",
      "ckb 48 0.798\n",
      "haw 44 0.608\n",
      "jbo 42 0.708\n",
      "ny 40 0.534\n",
      "ha 37 0.666\n",
      "nap 37 0.595\n",
      "gn 35 0.61\n",
      "ts 35 0.629\n",
      "ve 33 0.714\n",
      "ie 31 0.542\n",
      "fy 30 0.607\n",
      "om 26 0.783\n",
      "ast 26 0.492\n",
      "kha 25 0.824\n",
      "tlh 24 0.59\n",
      "io 24 0.742\n",
      "bi 23 0.511\n",
      "crs 23 0.844\n",
      "lmo 23 0.601\n",
      "kl 22 0.851\n",
      "kw 22 0.578\n",
      "to 21 0.786\n",
      "nds 21 0.535\n",
      "rn 20 0.6\n",
      "ss 16 0.586\n",
      "mfe 16 0.65\n",
      "vo 16 0.724\n",
      "fj 14 0.799\n",
      "pnb 14 0.846\n",
      "vec 14 0.544\n",
      "ba 13 0.807\n",
      "min 13 0.471\n",
      "mzn 12 0.653\n",
      "gv 11 0.743\n",
      "bo 11 1.0\n",
      "tg 10 0.626\n",
      "pms 9 0.623\n",
      "ps 8 0.872\n",
      "scn 8 0.732\n",
      "eml 7 0.814\n",
      "diq 7 0.563\n",
      "ce 7 0.887\n",
      "ilo 6 0.603\n",
      "wa 6 0.958\n",
      "hmn 5 0.892\n",
      "lo 5 0.922\n",
      "azb 5 0.844\n",
      "sd 4 0.664\n",
      "nah 4 0.863\n",
      "nso 3 0.616\n",
      "ay 3 0.639\n",
      "ks 3 0.977\n",
      "na 3 0.655\n",
      "ug 3 0.829\n",
      "syr 3 0.998\n",
      "sc 3 0.603\n",
      "new 3 0.448\n",
      "gom 3 0.72\n",
      "jp 2 0.847\n",
      "iu 2 0.643\n",
      "ik 2 0.756\n",
      "pam 2 0.512\n",
      "an 2 0.76\n",
      "bcl 2 0.514\n",
      "bar 2 0.859\n",
      "kv 2 0.898\n",
      "krc 2 0.92\n",
      "hsb 2 0.901\n"
     ]
    }
   ],
   "source": [
    "langs = [(k, len(v)) for k, v in lang_cers.items()]\n",
    "langs.sort(key=lambda x: (-x[1]))\n",
    "print(\"lang n_songs median cer\")\n",
    "cer_percentage_threshold = 0.5\n",
    "langs_cer_cut = {}\n",
    "for k, l_v in langs:\n",
    "    v = lang_cers[k]\n",
    "    if l_v > 1:\n",
    "        print(k, l_v, round(np.quantile(v, cer_percentage_threshold), 3))\n",
    "        langs_cer_cut[k] = round(np.quantile(v, cer_percentage_threshold), 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "bf85525f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:53:05.430409Z",
     "iopub.status.busy": "2025-04-22T00:53:05.429996Z",
     "iopub.status.idle": "2025-04-22T00:53:06.116868Z",
     "shell.execute_reply": "2025-04-22T00:53:06.116291Z",
     "shell.execute_reply.started": "2025-04-22T00:53:05.430390Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "language: en, n_songs: 1896824, median cer: 0.139\n",
      "language: es, n_songs: 241994, median cer: 0.11\n",
      "language: pt, n_songs: 130654, median cer: 0.13\n",
      "language: fr, n_songs: 123694, median cer: 0.188\n",
      "language: de, n_songs: 101101, median cer: 0.149\n",
      "language: it, n_songs: 79151, median cer: 0.103\n",
      "language: ru, n_songs: 77166, median cer: 0.155\n",
      "language: pl, n_songs: 63700, median cer: 0.142\n",
      "language: ko, n_songs: 47424, median cer: 0.185\n",
      "language: ja, n_songs: 46191, median cer: 0.251\n",
      "language: tr, n_songs: 40277, median cer: 0.146\n",
      "language: nl, n_songs: 16531, median cer: 0.217\n",
      "language: ar, n_songs: 14981, median cer: 0.283\n",
      "language: id, n_songs: 14411, median cer: 0.18\n",
      "language: hi, n_songs: 12288, median cer: 0.294\n",
      "language: iw, n_songs: 11926, median cer: 0.227\n",
      "language: el, n_songs: 11349, median cer: 0.303\n",
      "language: sv, n_songs: 10916, median cer: 0.243\n",
      "language: ro, n_songs: 10550, median cer: 0.211\n",
      "language: da, n_songs: 9459, median cer: 0.272\n",
      "language: fi, n_songs: 8397, median cer: 0.216\n",
      "language: zh, n_songs: 8057, median cer: 0.274\n",
      "language: sr, n_songs: 8026, median cer: 0.157\n",
      "language: tl, n_songs: 7966, median cer: 0.215\n",
      "language: cs, n_songs: 7420, median cer: 0.195\n",
      "language: hr, n_songs: 7147, median cer: 0.157\n",
      "language: vi, n_songs: 7115, median cer: 0.28\n",
      "language: no, n_songs: 6376, median cer: 0.274\n",
      "language: hu, n_songs: 5703, median cer: 0.262\n",
      "language: pa, n_songs: 5265, median cer: 0.276\n",
      "language: th, n_songs: 4541, median cer: 0.366\n",
      "language: fa, n_songs: 4503, median cer: 0.231\n",
      "language: romanization, n_songs: 4275, median cer: 0.54\n",
      "language: az, n_songs: 3961, median cer: 0.214\n",
      "language: zh-Hant, n_songs: 3640, median cer: 0.281\n",
      "language: sk, n_songs: 3628, median cer: 0.224\n",
      "language: uk, n_songs: 3130, median cer: 0.244\n",
      "language: bs, n_songs: 3036, median cer: 0.173\n",
      "language: bg, n_songs: 2264, median cer: 0.257\n",
      "language: sq, n_songs: 2030, median cer: 0.348\n",
      "language: ca, n_songs: 1935, median cer: 0.264\n",
      "language: af, n_songs: 1908, median cer: 0.219\n",
      "language: et, n_songs: 1826, median cer: 0.384\n",
      "language: ms, n_songs: 1775, median cer: 0.224\n",
      "language: he, n_songs: 1735, median cer: 0.201\n",
      "language: lv, n_songs: 1511, median cer: 0.341\n",
      "language: lt, n_songs: 1338, median cer: 0.367\n",
      "language: bn, n_songs: 1307, median cer: 0.221\n",
      "language: sl, n_songs: 1209, median cer: 0.285\n",
      "language: sw, n_songs: 1044, median cer: 0.379\n",
      "language: eu, n_songs: 1042, median cer: 0.391\n",
      "language: is, n_songs: 911, median cer: 0.492\n",
      "language: ne, n_songs: 866, median cer: 0.329\n",
      "language: la, n_songs: 754, median cer: 0.645\n",
      "language: ta, n_songs: 727, median cer: 0.374\n",
      "language: mr, n_songs: 628, median cer: 0.344\n",
      "language: mk, n_songs: 626, median cer: 0.321\n",
      "language: gl, n_songs: 599, median cer: 0.294\n",
      "language: zu, n_songs: 594, median cer: 0.526\n",
      "language: ht, n_songs: 545, median cer: 0.444\n",
      "language: co, n_songs: 494, median cer: 0.304\n",
      "language: si, n_songs: 445, median cer: 0.962\n",
      "language: eo, n_songs: 437, median cer: 0.383\n",
      "language: sco, n_songs: 426, median cer: 0.244\n",
      "language: am, n_songs: 362, median cer: 0.494\n",
      "language: ku, n_songs: 350, median cer: 0.587\n",
      "language: cy, n_songs: 328, median cer: 0.627\n",
      "language: te, n_songs: 328, median cer: 1.0\n",
      "language: ka, n_songs: 311, median cer: 0.486\n",
      "language: xh, n_songs: 294, median cer: 0.532\n",
      "language: mn, n_songs: 258, median cer: 0.626\n",
      "language: hy, n_songs: 257, median cer: 0.539\n",
      "language: ceb, n_songs: 244, median cer: 0.33\n",
      "language: als, n_songs: 230, median cer: 0.505\n",
      "language: war, n_songs: 228, median cer: 0.487\n",
      "language: ml, n_songs: 226, median cer: 1.0\n",
      "language: ga, n_songs: 221, median cer: 0.743\n",
      "language: uz, n_songs: 217, median cer: 0.535\n",
      "language: nn, n_songs: 202, median cer: 0.306\n",
      "language: my, n_songs: 196, median cer: 0.9\n",
      "language: kk, n_songs: 196, median cer: 0.534\n",
      "language: ln, n_songs: 186, median cer: 0.536\n",
      "language: yo, n_songs: 177, median cer: 0.445\n",
      "language: jv, n_songs: 176, median cer: 0.505\n",
      "language: sn, n_songs: 161, median cer: 0.49\n",
      "language: su, n_songs: 158, median cer: 0.492\n",
      "language: arz, n_songs: 158, median cer: 0.297\n",
      "language: rw, n_songs: 156, median cer: 0.521\n",
      "language: km, n_songs: 153, median cer: 0.952\n",
      "language: ur, n_songs: 146, median cer: 0.804\n",
      "language: be, n_songs: 130, median cer: 0.422\n",
      "language: sa, n_songs: 126, median cer: 0.544\n",
      "language: gd, n_songs: 114, median cer: 0.783\n",
      "language: lb, n_songs: 114, median cer: 0.503\n",
      "language: wo, n_songs: 112, median cer: 0.631\n",
      "language: kn, n_songs: 102, median cer: 1.0\n",
      "language: mg, n_songs: 101, median cer: 0.607\n",
      "language: br, n_songs: 99, median cer: 0.644\n",
      "language: jw, n_songs: 98, median cer: 0.443\n",
      "language: st, n_songs: 94, median cer: 0.562\n",
      "language: ak, n_songs: 91, median cer: 0.491\n",
      "language: sh, n_songs: 90, median cer: 0.274\n",
      "language: or, n_songs: 84, median cer: 1.0\n",
      "language: mi, n_songs: 82, median cer: 0.581\n",
      "language: bh, n_songs: 76, median cer: 0.468\n",
      "language: rm, n_songs: 75, median cer: 0.538\n",
      "language: oc, n_songs: 72, median cer: 0.524\n",
      "language: yi, n_songs: 72, median cer: 0.755\n",
      "language: ky, n_songs: 71, median cer: 0.484\n",
      "language: fo, n_songs: 70, median cer: 0.541\n",
      "language: lg, n_songs: 69, median cer: 0.54\n",
      "language: so, n_songs: 68, median cer: 0.658\n",
      "language: aa, n_songs: 56, median cer: 0.6\n",
      "language: tt, n_songs: 56, median cer: 0.672\n",
      "language: as, n_songs: 56, median cer: 0.402\n",
      "language: tk, n_songs: 55, median cer: 0.53\n",
      "language: ia, n_songs: 55, median cer: 0.26\n",
      "language: gu, n_songs: 53, median cer: 1.0\n",
      "language: ig, n_songs: 53, median cer: 0.539\n",
      "language: sm, n_songs: 51, median cer: 0.495\n",
      "language: tn, n_songs: 51, median cer: 0.576\n",
      "language: mt, n_songs: 50, median cer: 0.708\n",
      "language: qu, n_songs: 49, median cer: 0.467\n",
      "language: ckb, n_songs: 48, median cer: 0.641\n",
      "language: haw, n_songs: 44, median cer: 0.538\n",
      "language: jbo, n_songs: 42, median cer: 0.622\n",
      "language: ny, n_songs: 40, median cer: 0.451\n",
      "language: ha, n_songs: 37, median cer: 0.478\n",
      "language: nap, n_songs: 37, median cer: 0.512\n",
      "language: gn, n_songs: 35, median cer: 0.475\n",
      "language: ts, n_songs: 35, median cer: 0.585\n",
      "language: ve, n_songs: 33, median cer: 0.665\n",
      "language: ie, n_songs: 31, median cer: 0.436\n",
      "language: fy, n_songs: 30, median cer: 0.539\n",
      "language: om, n_songs: 26, median cer: 0.68\n",
      "language: ast, n_songs: 26, median cer: 0.4\n",
      "language: kha, n_songs: 25, median cer: 0.705\n",
      "language: tlh, n_songs: 24, median cer: 0.297\n",
      "language: io, n_songs: 24, median cer: 0.665\n",
      "language: bi, n_songs: 23, median cer: 0.419\n",
      "language: crs, n_songs: 23, median cer: 0.632\n",
      "language: lmo, n_songs: 23, median cer: 0.534\n",
      "language: kl, n_songs: 22, median cer: 0.795\n",
      "language: kw, n_songs: 22, median cer: 0.455\n",
      "language: to, n_songs: 21, median cer: 0.519\n",
      "language: nds, n_songs: 21, median cer: 0.432\n",
      "language: rn, n_songs: 20, median cer: 0.557\n",
      "language: ss, n_songs: 16, median cer: 0.43\n",
      "language: mfe, n_songs: 16, median cer: 0.5\n",
      "language: vo, n_songs: 16, median cer: 0.374\n",
      "language: fj, n_songs: 14, median cer: 0.661\n",
      "language: pnb, n_songs: 14, median cer: 0.755\n",
      "language: vec, n_songs: 14, median cer: 0.468\n",
      "language: ba, n_songs: 13, median cer: 0.688\n",
      "language: min, n_songs: 13, median cer: 0.436\n",
      "language: mzn, n_songs: 12, median cer: 0.569\n",
      "language: gv, n_songs: 11, median cer: 0.571\n",
      "language: bo, n_songs: 11, median cer: 0.984\n",
      "language: tg, n_songs: 10, median cer: 0.56\n",
      "language: pms, n_songs: 9, median cer: 0.536\n",
      "language: ps, n_songs: 8, median cer: 0.739\n",
      "language: scn, n_songs: 8, median cer: 0.663\n",
      "language: eml, n_songs: 7, median cer: 0.646\n",
      "language: diq, n_songs: 7, median cer: 0.45\n",
      "language: ce, n_songs: 7, median cer: 0.88\n",
      "language: ilo, n_songs: 6, median cer: 0.518\n",
      "language: wa, n_songs: 6, median cer: 0.751\n",
      "language: hmn, n_songs: 5, median cer: 0.58\n",
      "language: lo, n_songs: 5, median cer: 0.918\n",
      "language: azb, n_songs: 5, median cer: 0.669\n",
      "language: sd, n_songs: 4, median cer: 0.595\n",
      "language: nah, n_songs: 4, median cer: 0.708\n",
      "language: nso, n_songs: 3, median cer: 0.58\n",
      "language: ay, n_songs: 3, median cer: 0.58\n",
      "language: ks, n_songs: 3, median cer: 0.94\n",
      "language: na, n_songs: 3, median cer: 0.453\n",
      "language: ug, n_songs: 3, median cer: 0.699\n",
      "language: syr, n_songs: 3, median cer: 0.994\n",
      "language: sc, n_songs: 3, median cer: 0.449\n",
      "language: new, n_songs: 3, median cer: 0.409\n",
      "language: gom, n_songs: 3, median cer: 0.578\n",
      "language: jp, n_songs: 2, median cer: 0.839\n",
      "language: iu, n_songs: 2, median cer: 0.546\n",
      "language: ik, n_songs: 2, median cer: 0.737\n",
      "language: pam, n_songs: 2, median cer: 0.419\n",
      "language: an, n_songs: 2, median cer: 0.663\n",
      "language: bcl, n_songs: 2, median cer: 0.358\n",
      "language: bar, n_songs: 2, median cer: 0.806\n",
      "language: kv, n_songs: 2, median cer: 0.865\n",
      "language: krc, n_songs: 2, median cer: 0.89\n",
      "language: hsb, n_songs: 2, median cer: 0.864\n"
     ]
    }
   ],
   "source": [
    "langs = [(k, len(v)) for k, v in lang_cers.items()]\n",
    "langs.sort(key=lambda x: (-x[1]))\n",
    "cer_percentage_threshold = 0.3\n",
    "langs_cer_cut = {}\n",
    "for k, l_v in langs:\n",
    "    v = lang_cers[k]\n",
    "    if l_v > 1:\n",
    "        print(\n",
    "            f\"language: {k}, n_songs: {l_v}, median cer: {round(np.quantile(v, cer_percentage_threshold), 3)}\"\n",
    "        )\n",
    "        langs_cer_cut[k] = round(np.quantile(v, cer_percentage_threshold), 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "768780a2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T03:01:31.958520Z",
     "start_time": "2024-01-18T03:01:04.057834Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:53:19.945281Z",
     "iopub.status.busy": "2025-04-22T00:53:19.944853Z",
     "iopub.status.idle": "2025-04-22T00:54:05.622963Z",
     "shell.execute_reply": "2025-04-22T00:54:05.622391Z",
     "shell.execute_reply.started": "2025-04-22T00:53:19.945263Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 3101271/3101271 [00:45<00:00, 67902.00it/s]\n"
     ]
    }
   ],
   "source": [
    "rates = []\n",
    "cers = []\n",
    "# youtube_views_log = []\n",
    "for k in tqdm.tqdm(total_infos_2):\n",
    "    duration_s = metas_map[k][\"duration_s\"]\n",
    "    n_lyrics = len(metas_map[k][\"lyrics\"].split())\n",
    "    # print(n_lyrics / duration_s)\n",
    "    cers.append(total_infos_2[k])\n",
    "    rates.append(n_lyrics / duration_s)\n",
    "    # youtube_views_log.append(np.log10(metas_map[k][\"youtube_views\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "ddca3db4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-12T22:41:25.073971Z",
     "start_time": "2024-01-12T22:41:25.072066Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:05.623909Z",
     "iopub.status.busy": "2025-04-22T00:54:05.623752Z",
     "iopub.status.idle": "2025-04-22T00:54:05.626364Z",
     "shell.execute_reply": "2025-04-22T00:54:05.625967Z",
     "shell.execute_reply.started": "2025-04-22T00:54:05.623895Z"
    }
   },
   "outputs": [],
   "source": [
    "# plt.clf()\n",
    "# h = plt.hist2d(rates, youtube_views_log, bins=200)\n",
    "# plt.colorbar(h[3])\n",
    "# # plt.ylim(0, 4)\n",
    "# plt.xlim(0, 5)\n",
    "# plt.xlabel(\"n_words / sec\")\n",
    "# plt.ylabel(\"youtube_views, log10\")\n",
    "# plt.title(\"youtube views vs. num words per sec\")\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "2e5eb800",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-12T22:41:25.152543Z",
     "start_time": "2024-01-12T22:41:25.074881Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:05.626969Z",
     "iopub.status.busy": "2025-04-22T00:54:05.626830Z",
     "iopub.status.idle": "2025-04-22T00:54:05.628920Z",
     "shell.execute_reply": "2025-04-22T00:54:05.628536Z",
     "shell.execute_reply.started": "2025-04-22T00:54:05.626956Z"
    }
   },
   "outputs": [],
   "source": [
    "# plt.hist([r for r, v in zip(rates, youtube_views_log) if v < 6], bins=100, density=True, label=\"views < 1m\", alpha=0.5)\n",
    "# plt.hist([r for r, v in zip(rates, youtube_views_log) if v >= 6], bins=100, density=True, label=\"views >= 1m\", alpha=0.5)\n",
    "# plt.legend()\n",
    "# plt.xlabel(\"word rate / sec\")\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b19130f2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-12T22:41:25.212542Z",
     "start_time": "2024-01-12T22:41:25.153867Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:05.629914Z",
     "iopub.status.busy": "2025-04-22T00:54:05.629785Z",
     "iopub.status.idle": "2025-04-22T00:54:05.631923Z",
     "shell.execute_reply": "2025-04-22T00:54:05.631509Z",
     "shell.execute_reply.started": "2025-04-22T00:54:05.629901Z"
    }
   },
   "outputs": [],
   "source": [
    "# plt.clf()\n",
    "# h = plt.hist2d(cers, youtube_views_log, bins=100)\n",
    "# plt.colorbar(h[3])\n",
    "# # plt.ylim(0, 4)\n",
    "# # plt.xlim(0, 0.99)\n",
    "# plt.xlabel(\"cer\")\n",
    "# plt.ylabel(\"youtube_views\")\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "416b615d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T03:01:32.652951Z",
     "start_time": "2024-01-18T03:01:31.959970Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:05.632515Z",
     "iopub.status.busy": "2025-04-22T00:54:05.632380Z",
     "iopub.status.idle": "2025-04-22T00:54:06.532655Z",
     "shell.execute_reply": "2025-04-22T00:54:06.532120Z",
     "shell.execute_reply.started": "2025-04-22T00:54:05.632498Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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UJ3UAMC4ceMwbty4crfXq1evygERERHVTdL/Fi37121VSmpqPUk51UjyUF4myctTWd+noaJYYlDOJypsrHw/VqFB2f7NJsrmzF4Vly16ZR+jvWFUySKUzcoddEXK7bIbKt4ufGt0xULZQ9m+eHy3QmX8FndlfTfxeMLnoXO/vb/YtnhtdMXCZ2kWtuuFkxWupVhffGSn+LI3m/pmMyoiWYT6OiEAcXtJibLsXvGvsM1XQ3zGlPgIUvF4duK32V+sL1xem90r3qwgSRr71rXON3ATTkY4V0n47GSLk59tKlsq3CzGY49t/BVfb3vta92uhRi76nPT62//XPFldiwOP2lWqaTG19cXP/74I5o2bYrGjRtX+HbuP/74w2HBEREREVVWpZKaVatWwdvbGwCwevVqZ8ZDRERUN7GnRrNKJTUTJ04s82ciIiJyEL6lW7MqzamxWCw4d+4cLl26BItFOeDYr18/hwRGREREpIbqpObQoUMYO3YsLly4YDtJUpJgtjexkIiIiGzIsu3ce7X713Wqk5oZM2agV69e2LlzJwIDAyucNExERESVxDk1mqlOan766Sd88sknCA0NdUY8RERERFWi+kEKffr0wblz55wRCxERUd1VOlFYy1LHVaqn5sSJE9afn376aTz77LMwGo0ICwuDh4fywXJdunRxbIRERER1gCTfWrTsX9dVKqnp1q0bJElSTAx+4oknrD+XbuNEYSIioirinBrNKpXUZGVlOTsOIiIiIk0qldSEhIQ4Ow4iIqK6jQ/f04wvtCQiInIFHH7SzMmvkSUiIiKqHuypISIicgXsqdGMSQ0REZErYFKjmabhp6eeegpXrlxxVCxEREREVaYpqfnwww9hMpkcFQsREVHdxScKa6Zp+El8SzcRERFVDZ8orB3vfiIiIqJaQVNSc/36ddxzzz1V3j8hIQH33nsvvL294efnh5EjR+Ls2bN299u2bRvat28PLy8vhIWFYdeuXVWOgYiIyCXIDljqOE1JTXR0NHJycqq8/xdffIGYmBgcOnQIKSkpKC4uxuDBg1FQUFDuPunp6RgzZgymTJmC48ePY+TIkRg5ciROnTpV5TiIiIjo7qcpqTl48CBu3LhR5f13796NSZMmoVOnTujatSs2bdqE7OxsHD16tNx91qxZgyFDhmDu3Lno0KEDli5dih49emDt2rVVjoOI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2IuVbVmUlwqy0HcpuwkrbEITju8lVC8R/pUR4oHw4EhZuNaSWTx34QyliqcVSjrhwxLPx2ynvQr+pwOATfw29cWy0L5kZ/ud8cniF0c8F4vGx6nai0X87MRzsakvxid+O1XGI3yUsr32bD47tzKrWQn/zkg68bvhug85lcRTE78r9s5dYG7S8PbPJe7Az1WLq0qq+anA+/btQ3Z2Np544gnFer1ej3379mH16tUoKChAcHAwHnnkESxYsMBax83NDTt27MDMmTMRHh6OBg0aYOLEiYrn2rRu3Ro7d+5EbGws1qxZgxYtWuCdd95xyu3cQBWfU1P6JN879e7d2yEBERERUfUYPHhwmSMmwcHB+OKLL+zuHxISgl27dlVYZ8CAATh+/HiVY1SjUkmNmvcy2ZtoRERERLb47iftKpXUGAy3h2NkWcann34Kg8GAXr16AQCOHj2Ka9euqUp+iIiI6A41MKemtqlUUvPee+9Zf54/fz4ee+wxJCYmwu1/kyvMZjOeeuop1Xc/ERERETmK6plfGzduxD//+U9rQgPcmiwUFxeHjRs3OjQ4IiKiuqJ0+EnLUtepTmpKSkrwww8/2Kz/4YcfYFE7u5+IiIhukR2w1HGq736aPHkypkyZgvPnz1vveDp8+DCWLVuGyZMnOzxAIiIiospQndS8/vrrCAgIwIoVK5CTkwPg1tMF586di2effdbhARIREdUFvPtJO1VJTUlJCbZs2YKJEydi3rx5MJlMAMAJwkRERFrx7ifNVM2pcXd3x4wZM3Dz5q0n5qp9aRYRERGVg3NqNFM9Ubh3797V9mRAIiIiospSPafmqaeewrPPPotff/0VPXv2RIMGDRTbS190RURERJXHOTXaqU5qRo8eDQB45plnrOskSYIsy5AkCWazubxdiYiIqDycU6OZ6qQmKyvLGXEQERERaaI6qQkJCXFGHERERHWaJMuQynhjtpr96zrVSQ0AnD9/HqtXr8b3338PAOjYsSNmz56NNm3aODQ4IiKiOoPDT5qpvvtpz5496NixI7755ht06dIFXbp0weHDh9GpUyekpKQ4I0YiIiIiu1T31PzrX/9CbGwsli1bZrN+/vz5eOihhxwWHBERUV3Bu5+0U91T8/3332PKlCk265944gmcOXPGIUERERHVOXz4nmaqk5pmzZohMzPTZn1mZib8/PwcERMRERGRaqqHn6ZNm4bp06fj559/RkREBADg66+/xquvvoq4uDiHB0hERFQXcPhJO9VJzQsvvABvb2+sWLEC8fHxAICgoCAsXrxY8UA+IiIiUoF3P2mmOqmRJAmxsbGIjY3F9evXAQDe3t4OD4yIiKguYU+Ndqrn1GzcuNH6VGFvb28mNEREROQSVCc1CQkJCA0NRcuWLTF+/Hi88847OHfunDNiIyIiqjt495NmqpOan376CdnZ2UhISED9+vXx+uuvo127dmjRogX+8Y9/OCNGIiKiOqF0CKoqC1XxNQnNmzfHuHHj8PDDD+PLL7/ERx99hM2bNyMpKQkffviho2N0CsnNDZLkBgDQGXwU24qDfRXlvHv0ynJb5bfHO/SqonxP4z8U5c4+vynKXrriCmPLK6mnKOcWKuP701MZzxWP+sr93ZX75+s8FeUSN2X8lkI3ZVkMSCeJK5RF8ZdJKMvCi9t1JXZ2F5sXjn/nL6+sU+6tMwt1hWPLwjdeV6ysLx7boleusLgp6+vM4skq6+uKlAHIbsJ24drL7kIAJcKnIQYoHl/YLFmU+8s6ZQWbd8WUCBdMJNY3i/GJZaG+JFW8XXRHfQnKa2V3X7XvwRFjs7ddvLZidTchXoEsXivxWtq5VpK9eFWevyyJn53Qvtbj2fvs1Xw37MUifo1t/g2rmKlNA+vPJcVuwBFVu1MNUp3U7N27F2lpaUhLS8Px48fRoUMH9O/fH5988gn69evnjBiJiIhqP1lWn4yL+9dxqpOaIUOGoFmzZnj22Wexa9cuNGrUyAlhERER1S28+0k71XNqVq5cib59+2L58uXo1KkTxo4diw0bNuDHH390RnxERERElaI6qZkzZw62b9+OK1euYPfu3YiIiMDu3bvRuXNntGjRwhkxEhER1X68+0mzKk0UlmUZx48fR1paGg4cOICvvvoKFosFzZo1c3R8REREdYJkubVo2b+uU53UDB8+HF9//TVMJhO6du2KAQMGYNq0aejXrx/n1xAREVGNUZ3UtG/fHk8++SQeeOABGAwGZ8RERERU9/DdT5qpnlPz2muv4a9//avdhCYsLAwXL16ssM7BgwcxfPhwBAUFQZIkJCcn2z1+WloaevToAU9PT4SGhmLTpk0qoiciInJNWh68xwfw3aI6qamsX375BcXFFT9krqCgAF27dsW6desq1WZWVhaio6MxcOBAZGZmYs6cOZg6dSr27NnjiJCJiIhqTulzarQsKixevBiSJCmW9u3bW7ffvHkTMTExaNKkCRo2bIhHHnkEubm5ijays7MRHR2N+vXrw8/PD3PnzkVJifIJq9XZGVGlicKOMnToUAwdOrTS9RMTE9G6dWusWLECANChQwd89dVXWLVqFaKiopwVJhERUa3UqVMn7Nu3z1p2d7+dFsTGxmLnzp3Ytm0bDAYDZs2ahVGjRuHrr78GAJjNZkRHRyMgIADp6enIycnBhAkT4OHhgVdeeQXA7c6IGTNmYPPmzUhNTcXUqVMRGBjolL/bNZrUqJWRkYHIyEjFuqioKMyZM6fcfQoLC1FYWGgtm0wmZ4VHRERUZTXx8D13d3cEBATYrM/Ly8O7776LLVu24MEHHwQAvPfee+jQoQMOHTqE++67D3v37sWZM2ewb98++Pv7o1u3bli6dCnmz5+PxYsXQ6/XV3tnhNOGn5zBaDTC399fsc7f3x8mkwk3btwoc5+EhAQYDAbrEhwcXB2hEhERqeOg59SYTCbFcuf/2It++uknBAUF4Z577sG4ceOQnZ0NADh69CiKi4sVHQnt27dHy5YtkZGRAeBWR0NYWJji73JUVBRMJhNOnz5trVNWZ0RpG452VyU1VREfH4+8vDzrYm/yMhER0d0sODhY8T/zCQkJZdbr06cPNm3ahN27d2P9+vXIysrCAw88gOvXr8NoNEKv19s8qsXf3x9GoxFA+R0NpdsqqlNRZ4QWd9XwU0BAgM0kpdzcXPj4+KBevXpl7uPp6QlPT88ytxEREbkKRw0/Xbx4ET4+Ptb15f0NvHNOa5cuXdCnTx+EhIRg69at5f5NdXVO66l56623bLIzrcLDw5GamqpYl5KSgvDwcIceh4iIqNo56O4nHx8fxVLZ/7Fv1KgR/vKXv+DcuXMICAhAUVERrl27pqiTm5trnYNTXkdD6baK6lTUGaFFlXpqUlNTkZqaikuXLsFiUT6XeePGjQCAsWPH2m0nPz8f586ds5azsrKQmZkJX19ftGzZEvHx8fjvf/+LDz74AAAwY8YMrF27FvPmzcMTTzyB/fv3Y+vWrdi5c2dVToOIiIj+Jz8/H+fPn8f48ePRs2dPeHh4IDU1FY888ggA4OzZs8jOzrZ2JISHh+Pll1/GpUuX4OfnB+BWR4OPjw86duxorbNr1y7FcZzZGaG6p2bJkiUYPHgwUlNTceXKFVy9elWxqHHkyBF0794d3bt3BwDExcWhe/fuWLhwIQAgJyfHOmkJAFq3bo2dO3ciJSUFXbt2xYoVK/DOO+/wdm4iIrrrVffD9/75z3/iiy++wC+//IL09HQ8/PDDcHNzw5gxY2AwGDBlyhTExcXhwIEDOHr0KCZPnozw8HDcd999AIDBgwejY8eOGD9+PL777jvs2bMHCxYsQExMjLV3aMaMGfj5558xb948/PDDD3jzzTexdetWxMbGOvryAahCT01iYiI2bdqE8ePHaz74gAEDIFfwsKCyHtAzYMAAHD9+XPOxiYiIXEo1vybh119/xZgxY/D777+jWbNmuP/++3Ho0CHry6lXrVoFnU6HRx55BIWFhYiKisKbb75p3d/NzQ07duzAzJkzER4ejgYNGmDixIl48cUXrXVKOyNiY2OxZs0atGjRwqmdEaqTmqKiIkRERDgjFiIiIqomSUlJFW738vLCunXrKnzqf0hIiM3wkqg6OyNUDz9NnToVW7ZscUYsREREdRbf/aSd6p6amzdvYsOGDdi3bx+6dOkCDw8PxfaVK1c6LDgiIqI6wyLfWrTsX8epTmpOnDiBbt26AQBOnTql2CZJkkOCIiIiqnOqeU5NbaQ6qTlw4IAz4iAiIiLS5K56ojAREVFtJUHjE4UdFsndi0kNERGRK7jjqcBV3r+Oq7NJjeThBkn63+m7uSm2yUK661ao/KLoryor5F00KMqZefUV5XPeTZXtuSmfwuymU5aLipUfS3GJMr6im8rtlmIh/hJlfFKR8iY3nVB2v6ms71akKEKyCOUSZVlXXHFZHOfVCfvbtC+Uxfq6ktsNSmZhm1AWf8nF+uJ2i7vyWsg64csgFG22C+3JbsprbdGLZeGzc1dul4T2JXEioE4ouwnxlygvpti+LF57YbvNP5JifXv/iIrbxXl3knA88Xreeb5isGbxiyJVvN3enD9xf5vtys8KxcovuuQu/HMqHs+s/PJJENpzsxOvzWdR8bWXxetlp77NZ2kRr6/Km2XF/dW683j2YrG33e5nr6xvHHz7s7XcKAa2Vrw7uY46m9QQERG5Eke90LIuY1JDRETkCnj3k2ZOe0s3ERERUXViTw0REZELkGTZ/jw1O/vXdUxqiIiIXIEFNpPxVe9fx3H4iYiIiGoF9tQQERG5AA4/acekhoiIyBXw7ifNmNQQERG5Aj5RWDPOqSEiIqJagT01RERELoBPFNaOSQ0REZEr4PCTZhx+IiIiolqBPTVEREQuQLLcWrTsX9cxqSEiInIFHH7SjMNPREREVCuwp4aIiMgV8OF7mjGpISIicgF8TYJ2HH4iIiKiWoE9NURERK6AE4U1Y1JDRETkCmQAWm7LZk7DpIaIiMgVcE6NdpxTQ0RERLUCe2qIiIhcgQyNc2ocFsldi0kNERGRK+BEYc2Y1ACQ80yKsv4ns6LcNLehoux7Qq8omxt6Kstebsqyp3J/i7ukPL4wCFhP/F7a+Z7qzEIFm/rKFZKsPD+ppOIDSGL74nbxF8nORDfJIsZrp32hvqy7ff10YuxiW3aunWRRBiu7KT8M3Z/Fyh3chQ/L5nh2roWwv3SzSLldZ6d9kbhdJ7avjF9ys9O++NmIhOsFSfldtmnPLNR3V/5uwKL8LkIW2quoLZ1QV4xdjE2sL7Zn53tu/1yFcxHrqyXGp5V4/iLxcOJ30d752PkuOpS9WNzcKt5up72fB79r/dl03YzG6lqjGsSkhoiIyBVYAGjJhflCS9eYKLxu3Tq0atUKXl5e6NOnD7755pty627atAmSJCkWLy+vaoyWiIjI8UrvftKy1HU1ntR8/PHHiIuLw6JFi3Ds2DF07doVUVFRuHTpUrn7+Pj4ICcnx7pcuHChGiMmIiK6+yUkJODee++Ft7c3/Pz8MHLkSJw9e1ZRZ8CAATYdCTNmzFDUyc7ORnR0NOrXrw8/Pz/MnTsXJSUlijppaWno0aMHPD09ERoaik2bNjnlnGo8qVm5ciWmTZuGyZMno2PHjkhMTET9+vWxcePGcveRJAkBAQHWxd/fvxojJiIicoLSicJaFhW++OILxMTE4NChQ0hJSUFxcTEGDx6MgoICRb1p06YpOhKWL19u3WY2mxEdHY2ioiKkp6fj/fffx6ZNm7Bw4UJrnaysLERHR2PgwIHIzMzEnDlzMHXqVOzZs0fb9SpDjc6pKSoqwtGjRxEfH29dp9PpEBkZiYyMjHL3y8/PR0hICCwWC3r06IFXXnkFnTp1qo6QiYiInKOa737avXu3orxp0yb4+fnh6NGj6Nevn3V9/fr1ERAQUGYbe/fuxZkzZ7Bv3z74+/ujW7duWLp0KebPn4/FixdDr9cjMTERrVu3xooVKwAAHTp0wFdffYVVq1YhKipK5UlWrEZ7aq5cuQKz2WzT0+Lv7w+j0VjmPu3atcPGjRvx2Wef4cMPP4TFYkFERAR+/fXXMusXFhbCZDIpFiIiotpK/JtXWFhYqf3y8vIAAL6+vor1mzdvRtOmTdG5c2fEx8fjzz//tG7LyMhAWFiY4u94VFQUTCYTTp8+ba0TGRmpaDMqKqrCzouquuvufgoPD0d4eLi1HBERgQ4dOuCtt97C0qVLbeonJCRgyZIl1RkiERGReg7qqQkODlasXrRoERYvXlzhrhaLBXPmzEHfvn3RuXNn6/qxY8ciJCQEQUFBOHHiBObPn4+zZ89i+/btAACj0Vhmx0TptorqmEwm3LhxA/Xq1VN/ruWo0aSmadOmcHNzQ25urmJ9bm5uuV1dIg8PD3Tv3h3nzp0rc3t8fDzi4uKsZZPJZPOBExER1TgH3dJ98eJF+Pj4WFd7enqWs8NtMTExOHXqFL766ivF+unTp1t/DgsLQ2BgIAYNGoTz58+jTZs2GoJ1jhodftLr9ejZsydSU1Ot6ywWC1JTUxW9MRUxm804efIkAgMDy9zu6ekJHx8fxUJERORqHHVLt/g3z15SM2vWLOzYsQMHDhxAixYtKqzbp08fALB2JAQEBJTZMVG6raI6Pj4+Du2lAVzg7qe4uDi8/fbbeP/99/H9999j5syZKCgowOTJkwEAEyZMUEwkfvHFF7F37178/PPPOHbsGP7xj3/gwoULmDp1ak2dAhER0V1HlmXMmjULn376Kfbv34/WrVvb3SczMxMArB0J4eHhOHnypOIxLCkpKfDx8UHHjh2tde7svCitU9nOCzVqfE7N448/jsuXL2PhwoUwGo3o1q0bdu/ebR1/y87Ohu6Ox21fvXoV06ZNg9FoROPGjdGzZ0+kp6dbLx4REdFdqZrvfoqJicGWLVvw2Wefwdvb2zoHxmAwoF69ejh//jy2bNmCYcOGoUmTJjhx4gRiY2PRr18/dOnSBQAwePBgdOzYEePHj8fy5cthNBqxYMECxMTEWHuIZsyYgbVr12LevHl44oknsH//fmzduhU7d+6s+rmWQ5LluvUIQpPJBIPBgAfrPQ536dY7nCR3ZW4nNWyg3MlHeHdTfbXvflJ2iNl795Pk8Hc/Vdw+3/10R/Va/u4nuNq7n4qE86/onT5q3/0ksvfuJ3vE2IuVDxeD8LAx1e9+Eq+tvfOxQ5ZVnp+930u1735yJPHaiO92Et+7pfa9U8K57TrzhfVn03UzGv/lZ+Tl5Tlt+kLp36XINnPg7mZ//kt5SsyF2Hd+daVjlcr5TN977z1MmjQJFy9exD/+8Q+cOnUKBQUFCA4OxsMPP4wFCxYo2r9w4QJmzpyJtLQ0NGjQABMnTsSyZcvgfsff1rS0NMTGxuLMmTNo0aIFXnjhBUyaNKnK51qeGu+pISIioupnr08jODgYX3zxRYV1ACAkJAS7du2qsM6AAQNw/PhxVfFVBZMaIiIiV1DNw0+1EZMaIiIil6AxqbE33l4H1PjdT0RERESOwJ4aIiIiV8DhJ82Y1BAREbkCiwxNQ0ga75irDTj8RERERLUCe2qIiIhcgWy5tWjZv45jUkNEROQKOKdGMyY1REREroBzajTjnBoiIiKqFdhTQ0RE5Ao4/KQZkxoiIiJXIENjUuOwSO5adTapkdzcIEm33vRqzi9QbvvzT2Xly79X2Jab8PZfN7GCJIzyiW8LFt6UKolvmBXfSCvWF7eLb2K2iUc4vng8e29etrfdHq373/nGXrVvsRbf+C3cLSAJn5Usvv1XpPVN0eKbnsXPQnw7sUr2Xlhnw85nI2uMR/xu21xfrd8NZ7IXW03PZ7B354v475Cj2bwF3c7vjr141NzJI7Yl7qvy3G/IhXf8zDuK7iZ1NqkhIiJyKRx+0oxJDRERkSuwWABo6BnS2JNaG/DuJyIiIqoV2FNDRETkCjj8pBmTGiIiIlfApEYzDj8RERFRrcCeGiIiIlfA1yRoxqSGiIjIBciyxebZWWr3r+uY1BAREbkCWdbW28I5NZxTQ0RERLUDe2qIiIhcgaxxTg17apjUEBERuQSLBZA0zIvhnBoOPxEREVHtwJ4aIiIiV8DhJ82Y1BAREbkA2WKBrGH4ibd0c/iJiIiIagn21BAREbkCDj9pxqSGiIjIFVhkQGJSowWHn4iIiKhWYE8NERGRK5BlAFqeU8OeGiY1RERELkC2yJA1DD/JTGqY1BAREbkE2QJtPTW8pdsl5tSsW7cOrVq1gpeXF/r06YNvvvmmwvrbtm1D+/bt4eXlhbCwMOzatauaIiUiIqpd1P4NdmU1ntR8/PHHiIuLw6JFi3Ds2DF07doVUVFRuHTpUpn109PTMWbMGEyZMgXHjx/HyJEjMXLkSJw6daqaIyciInIc2SJrXtRS+zfY1dV4UrNy5UpMmzYNkydPRseOHZGYmIj69etj48aNZdZfs2YNhgwZgrlz56JDhw5YunQpevTogbVr11Zz5ERERA4kW7QvKqn9G+zqanROTVFREY4ePYr4+HjrOp1Oh8jISGRkZJS5T0ZGBuLi4hTroqKikJycXGb9wsJCFBYWWst5eXkAgBK52LrOfMfPACDJktBKxbmfbX2bGsqiTX1lWZKF48luFde3CNslO7mqZOf8xO3i5DN72+3Rur/ljl9ce/uK24X/kxEfKy4J106WzXZiUXkuNvVLhLL42WscI1c9cbDi89H6GHbxu217fTV+N5zKTmw1Havd49v7d0rr8cXrY++7YiceVdfT3vdG3bmbrt+O/Xq+5X9NOv/zLUGxpmfvleDW3zKTyaRY7+npCU9PT5v6Vfkb7OpqNKm5cuUKzGYz/P39Fev9/f3xww8/lLmP0Wgss77RaCyzfkJCApYsWWKz/ouCbeUHZufvGBER1V5B7WzX/f777zAYDE45nl6vR0BAAL4yap8f2rBhQwQHByvWLVq0CIsXL7apW5W/wa6u1t/9FB8fr+jZuXbtGkJCQpCdne20L2htZjKZEBwcjIsXL8LHx6emw7mr8NpVHa+dNrx+VZeXl4eWLVvC19fXacfw8vJCVlYWioqKNLclyzIkoTe8rF6a2qpGk5qmTZvCzc0Nubm5ivW5ubkICAgoc5+AgABV9cvrdjMYDPzl1sDHx4fXr4p47aqO104bXr+q0+mcOwXVy8sLXl5eTj2GqCp/g11djU4U1uv16NmzJ1JTU63rLBYLUlNTER4eXuY+4eHhivoAkJKSUm59IiIislWVv8GursaHn+Li4jBx4kT06tULvXv3xurVq1FQUIDJkycDACZMmIDmzZsjISEBADB79mz0798fK1asQHR0NJKSknDkyBFs2LChJk+DiIjormPvb/DdpsaTmscffxyXL1/GwoULYTQa0a1bN+zevds6cSk7O1vR7RcREYEtW7ZgwYIFeO6559C2bVskJyejc+fOlTqep6cnFi1aVKfGGB2J16/qeO2qjtdOG16/qqvt187e3+C7jSTzZRFERERUC9T4w/eIiIiIHIFJDREREdUKTGqIiIioVmBSQ0RERLVCrUxq1L5Gfdu2bWjfvj28vLwQFhaGXbu0P6r6bqbm+r399tt44IEH0LhxYzRu3BiRkZF39WvrtVL73SuVlJQESZIwcuRI5wbowtReu2vXriEmJgaBgYHw9PTEX/7ylzr9u6v2+q1evRrt2rVDvXr1EBwcjNjYWNy8ebOaonUdBw8exPDhwxEUFARJksp9j+Cd0tLS0KNHD3h6eiI0NBSbNm1yepxUSXItk5SUJOv1ennjxo3y6dOn5WnTpsmNGjWSc3Nzy6z/9ddfy25ubvLy5cvlM2fOyAsWLJA9PDzkkydPVnPkrkHt9Rs7dqy8bt06+fjx4/L3338vT5o0STYYDPKvv/5azZHXPLXXrlRWVpbcvHlz+YEHHpBHjBhRPcG6GLXXrrCwUO7Vq5c8bNgw+auvvpKzsrLktLQ0OTMzs5ojdw1qr9/mzZtlT09PefPmzXJWVpa8Z88eOTAwUI6Nja3myGverl275Oeff17evn27DED+9NNPK6z/888/y/Xr15fj4uLkM2fOyG+88Ybs5uYm7969u3oCpgrVuqSmd+/eckxMjLVsNpvloKAgOSEhocz6jz32mBwdHa1Y16dPH/nJJ590apyuSu31E5WUlMje3t7y+++/76wQXVZVrl1JSYkcEREhv/POO/LEiRPrbFKj9tqtX79evueee+SioqLqCtGlqb1+MTEx8oMPPqhYFxcXJ/ft29epcbq6yiQ18+bNkzt16qRY9/jjj8tRUVFOjIwqq1YNP5W+Rj0yMtK6zt5r1DMyMhT1ASAqKuqufe26FlW5fqI///wTxcXFTn35myuq6rV78cUX4efnhylTplRHmC6pKtfuP//5D8LDwxETEwN/f3907twZr7zyCsxmc3WF7TKqcv0iIiJw9OhR6xDVzz//jF27dmHYsGHVEvPdjH8zXFuNP1HYkaryGnWj0VhmfaPR6LQ4XZUjXkM/f/58BAUF2fzS13ZVuXZfffUV3n33XWRmZlZDhK6rKtfu559/xv79+zFu3Djs2rUL586dw1NPPYXi4mIsWrSoOsJ2GVW5fmPHjsWVK1dw//33Q5ZllJSUYMaMGXjuueeqI+S7Wnl/M0wmE27cuIF69erVUGQE1NKJwlQzli1bhqSkJHz66afV/rbZu83169cxfvx4vP3222jatGlNh3PXsVgs8PPzw4YNG9CzZ088/vjjeP7555GYmFjTod0V0tLS8Morr+DNN9/EsWPHsH37duzcuRNLly6t6dCINKlVPTVVeY16QEBArXrtuhZaXkP/+uuvY9myZdi3bx+6dOnizDBdktprd/78efzyyy8YPny4dZ3FYgEAuLu74+zZs2jTpo1zg3YRVfneBQYGwsPDA25ubtZ1HTp0gNFoRFFREfR6vVNjdiVVuX4vvPACxo8fj6lTpwIAwsLCUFBQgOnTp+P5559XvG+PlMr7m+Hj48NeGhdQq765VXmNenh4uKI+AKSkpNy1r13XoqqvoV++fDmWLl2K3bt3o1evXtURqstRe+3at2+PkydPIjMz07r87W9/w8CBA5GZmYng4ODqDL9GVeV717dvX5w7d86aCALAjz/+iMDAwDqV0ABVu35//vmnTeJSmiDKfB1ghfg3w8XV9ExlR0tKSpI9PT3lTZs2yWfOnJGnT58uN2rUSDYajbIsy/L48ePlf/3rX9b6X3/9tezu7i6//vrr8vfffy8vWrSozt/Sreb6LVu2TNbr9fInn3wi5+TkWJfr16/X1CnUGLXXTlSX735Se+2ys7Nlb29vedasWfLZs2flHTt2yH5+fvJLL71UU6dQo9Rev0WLFsne3t7yRx99JP/888/y3r175TZt2siPPfZYTZ1Cjbl+/bp8/Phx+fjx4zIAeeXKlfLx48flCxcuyLIsy//617/k8ePHW+uX3tI9d+5c+fvvv5fXrVvHW7pdSK1LamRZlt944w25ZcuWsl6vl3v37i0fOnTIuq1///7yxIkTFfW3bt0q/+Uvf5H1er3cqVMneefOndUcsWtRc/1CQkJkADbLokWLqj9wF6D2u3enupzUyLL6a5eeni736dNH9vT0lO+55x755ZdflktKSqo5ateh5voVFxfLixcvltu0aSN7eXnJwcHB8lNPPSVfvXq1+gOvYQcOHCjz37DS6zVx4kS5f//+Nvt069ZN1uv18j333CO/99571R43lU2SZfY1EhER0d2vVs2pISIiorqLSQ0RERHVCkxqiIiIqFZgUkNERES1ApMaIiIiqhWY1BAREVGtwKSGiIiIagUmNURERFQrMKkhIiKiWoFJDRGpVlRUVNMhEBHZYFJDVEdYLBYsX74coaGh8PT0RMuWLfHyyy8DAC5evIjHHnsMjRo1gq+vL0aMGIFffvnFuu+kSZMwcuRIvPzyywgKCkK7du1q6CyIiMrnXtMBEFH1iI+Px9tvv41Vq1bh/vvvR05ODn744QcUFxcjKioK4eHh+PLLL+Hu7o6XXnoJQ4YMwYkTJ6DX6wEAqamp8PHxQUpKSg2fCRFR2fhCS6I64Pr162jWrBnWrl2LqVOnKrZ9+OGHeOmll/D9999DkiQAt4aXGjVqhOTkZAwePBiTJk3C7t27kZ2dbU1yiIhcDXtqiOqA77//HoWFhRg0aJDNtu+++w7nzp2Dt7e3Yv3Nmzdx/vx5azksLIwJDRG5NCY1RHVAvXr1yt2Wn5+Pnj17YvPmzTbbmjVrZv25QYMGTomNiMhROFGYqA5o27Yt6tWrh9TUVJttPXr0wE8//QQ/Pz+EhoYqFoPBUAPREhFVDZMaojrAy8sL8+fPx7x58/DBBx/g/PnzOHToEN59912MGzcOTZs2xYgRI/Dll18iKysLaWlpeOaZZ/Drr7/WdOhERJXG4SeiOuKFF16Au7s7Fi5ciN9++w2BgYGYMWMG6tevj4MHD2L+/PkYNWoUrl+/jubNm2PQoEHw8fGp6bCJiCqNdz8RERFRrcDhJyIiIqoVmNQQERFRrcCkhoiIiGoFJjVERERUKzCpISIiolqBSQ0RERHVCkxqiIiIqFZgUkNERES1ApMaIiIiqhWY1BAREVGtwKSGiIiIagUmNURERFQr/H/tdFfPHT811QAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.clf()\n",
    "h = plt.hist2d(cers, rates, bins=100)\n",
    "plt.colorbar(h[3])\n",
    "plt.ylim(0, 4)\n",
    "# plt.xlim(0, 0.99)\n",
    "plt.xlabel(\"cer\")\n",
    "plt.ylabel(\"n_words / sec  -- higher faster\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "2172be9d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-18T03:01:36.428046Z",
     "start_time": "2024-01-18T03:01:32.654154Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:06.533367Z",
     "iopub.status.busy": "2025-04-22T00:54:06.533218Z",
     "iopub.status.idle": "2025-04-22T00:54:14.000549Z",
     "shell.execute_reply": "2025-04-22T00:54:14.000065Z",
     "shell.execute_reply.started": "2025-04-22T00:54:06.533352Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAGdCAYAAAD+JxxnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA1j0lEQVR4nO3df3QU9b3/8VcS3A1QNvxqfn0JEBFFJEAJGlcFpeawamqblt7yw2LECIUGKkmFEMXwQ9vQUBGsSI4/Q0+hKPcIbQONxihwLStIIEUQckGD6IENWEkWoiQkme8fnsxlCUoWswnJPB/nzCk7n/fMvudTZV/OzswGGYZhCAAAwIKC27oBAACAtkIQAgAAlkUQAgAAlkUQAgAAlkUQAgAAlkUQAgAAlkUQAgAAlkUQAgAAltWprRu4kjU0NOjYsWPq1q2bgoKC2rodAADQDIZh6PTp04qOjlZw8Lef8yEIfYtjx44pJiamrdsAAACX4dNPP1WfPn2+tYYg9C26desm6euJdDgcbdwNAABoDq/Xq5iYGPNz/NsQhL5F49dhDoeDIAQAQDvTnMtauFgaAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYFkEIAABYVqe2bgDW1X/epmbVHVmSFOBOAABWxRkhAABgWQQhAABgWXw1hoBo7tdeAAC0Jc4IAQAAyyIIAQAAyyIIAQAAy+IaIfiN638AAB0FZ4QAAIBlEYQAAIBlEYQAAIBlEYQAAIBl+RWEcnJydOONN6pbt24KDw9XcnKyysrKfGrOnj2rtLQ09erVS9/73vc0btw4VVRU+NQcPXpUSUlJ6tKli8LDwzVnzhzV1dX51GzZskUjRoyQ3W7XNddco/z8/Cb9rFy5Uv3791doaKgSEhK0c+dOv3sBAADW5VcQ2rp1q9LS0vTee++pqKhI586d09ixY1VdXW3WpKen6x//+IfWr1+vrVu36tixY/rZz35mjtfX1yspKUm1tbXavn27Vq9erfz8fGVnZ5s15eXlSkpK0pgxY1RaWqrZs2froYce0htvvGHWvPrqq8rIyNCCBQu0e/duDRs2TC6XSydOnGh2LwAAwNqCDMMwLnfjkydPKjw8XFu3btXo0aNVVVWl73//+1q7dq1+/vOfS5IOHjyo66+/Xm63WzfffLP++c9/6kc/+pGOHTumiIgISVJeXp4yMzN18uRJ2Ww2ZWZmatOmTdq3b5/5XhMmTFBlZaUKCwslSQkJCbrxxhv17LPPSpIaGhoUExOjWbNmad68ec3q5VK8Xq/CwsJUVVUlh8NxudPU4bT27fP8+jwAwB/+fH5/p2uEqqqqJEk9e/aUJJWUlOjcuXNKTEw0awYNGqS+ffvK7XZLktxut+Li4swQJEkul0ter1f79+83a87fR2NN4z5qa2tVUlLiUxMcHKzExESzpjm9AAAAa7vsByo2NDRo9uzZuvXWWzVkyBBJksfjkc1mU/fu3X1qIyIi5PF4zJrzQ1DjeOPYt9V4vV599dVXOnXqlOrr6y9ac/DgwWb3cqGamhrV1NSYr71e76WmAQAAtGOXfUYoLS1N+/bt07p161qynzaVk5OjsLAwc4mJiWnrlgAAQABdVhCaOXOmCgoK9M4776hPnz7m+sjISNXW1qqystKnvqKiQpGRkWbNhXduNb6+VI3D4VDnzp3Vu3dvhYSEXLTm/H1cqpcLZWVlqaqqylw+/fTTZswGAABor/wKQoZhaObMmdqwYYPefvttxcbG+ozHx8frqquuUnFxsbmurKxMR48eldPplCQ5nU598MEHPnd3FRUVyeFwaPDgwWbN+ftorGnch81mU3x8vE9NQ0ODiouLzZrm9HIhu90uh8PhswAAgI7Lr2uE0tLStHbtWv3tb39Tt27dzGttwsLC1LlzZ4WFhSk1NVUZGRnq2bOnHA6HZs2aJafTad6lNXbsWA0ePFiTJ09Wbm6uPB6P5s+fr7S0NNntdknS9OnT9eyzz2ru3Ll68MEH9fbbb+u1117Tpk3/d7dSRkaGUlJSNHLkSN10001avny5qqurNWXKFLOnS/UCAACsza8gtGrVKknSHXfc4bP+lVde0QMPPCBJevrppxUcHKxx48appqZGLpdLzz33nFkbEhKigoICzZgxQ06nU127dlVKSooWL15s1sTGxmrTpk1KT0/XihUr1KdPH7344otyuVxmzfjx43Xy5EllZ2fL4/Fo+PDhKiws9LmA+lK9oCl+WR4AYCXf6TlCHZ0VnyN0JQYhniMEAPBHqz1HCAAAoD0jCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMsiCAEAAMvq1NYNAJfSf96mS9YcWZLUCp0AADoazggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADL8jsIbdu2Tffee6+io6MVFBSkjRs3+owHBQVddFm6dKlZ079//ybjS5Ys8dnP3r17NWrUKIWGhiomJka5ublNelm/fr0GDRqk0NBQxcXFafPmzT7jhmEoOztbUVFR6ty5sxITE3Xo0CF/DxkAAHRQfgeh6upqDRs2TCtXrrzo+PHjx32Wl19+WUFBQRo3bpxP3eLFi33qZs2aZY55vV6NHTtW/fr1U0lJiZYuXaqFCxfq+eefN2u2b9+uiRMnKjU1VXv27FFycrKSk5O1b98+syY3N1fPPPOM8vLytGPHDnXt2lUul0tnz57197ABAEAH5PePrt599926++67v3E8MjLS5/Xf/vY3jRkzRldffbXP+m7dujWpbbRmzRrV1tbq5Zdfls1m0w033KDS0lItW7ZM06ZNkyStWLFCd911l+bMmSNJeuKJJ1RUVKRnn31WeXl5MgxDy5cv1/z58/WTn/xEkvTnP/9ZERER2rhxoyZMmODvoQMAgA4moNcIVVRUaNOmTUpNTW0ytmTJEvXq1Us/+MEPtHTpUtXV1Zljbrdbo0ePls1mM9e5XC6VlZXp1KlTZk1iYqLPPl0ul9xutySpvLxcHo/HpyYsLEwJCQlmDQAAsDa/zwj5Y/Xq1erWrZt+9rOf+az/zW9+oxEjRqhnz57avn27srKydPz4cS1btkyS5PF4FBsb67NNRESEOdajRw95PB5z3fk1Ho/HrDt/u4vVXKimpkY1NTXma6/X6+8ho430n7fpkjVHliS1QicAgPYkoEHo5Zdf1n333afQ0FCf9RkZGeafhw4dKpvNpl/96lfKycmR3W4PZEvfKicnR4sWLWqz9wcAAK0rYF+N/c///I/Kysr00EMPXbI2ISFBdXV1OnLkiKSvrzOqqKjwqWl83Xhd0TfVnD9+/nYXq7lQVlaWqqqqzOXTTz+9ZO8AAKD9ClgQeumllxQfH69hw4Zdsra0tFTBwcEKDw+XJDmdTm3btk3nzp0za4qKinTdddepR48eZk1xcbHPfoqKiuR0OiVJsbGxioyM9Knxer3asWOHWXMhu90uh8PhswAAgI7L76/Gzpw5o8OHD5uvy8vLVVpaqp49e6pv376Svg4c69ev11NPPdVke7fbrR07dmjMmDHq1q2b3G630tPT9ctf/tIMOZMmTdKiRYuUmpqqzMxM7du3TytWrNDTTz9t7ufhhx/W7bffrqeeekpJSUlat26ddu3aZd5iHxQUpNmzZ+vJJ5/UwIEDFRsbq8cff1zR0dFKTk7297ABAEAH5HcQ2rVrl8aMGWO+brzeJyUlRfn5+ZKkdevWyTAMTZw4scn2drtd69at08KFC1VTU6PY2Filp6f7XDcUFhamN998U2lpaYqPj1fv3r2VnZ1t3jovSbfccovWrl2r+fPn69FHH9XAgQO1ceNGDRkyxKyZO3euqqurNW3aNFVWVuq2225TYWFhk2uWAACANQUZhmG0dRNXKq/Xq7CwMFVVVVnma7Lm3H3VXnHXGABYgz+f3/zWGAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCy/g9C2bdt07733Kjo6WkFBQdq4caPP+AMPPKCgoCCf5a677vKp+eKLL3TffffJ4XCoe/fuSk1N1ZkzZ3xq9u7dq1GjRik0NFQxMTHKzc1t0sv69es1aNAghYaGKi4uTps3b/YZNwxD2dnZioqKUufOnZWYmKhDhw75e8gAAKCD8jsIVVdXa9iwYVq5cuU31tx11106fvy4ufz1r3/1Gb/vvvu0f/9+FRUVqaCgQNu2bdO0adPMca/Xq7Fjx6pfv34qKSnR0qVLtXDhQj3//PNmzfbt2zVx4kSlpqZqz549Sk5OVnJysvbt22fW5Obm6plnnlFeXp527Nihrl27yuVy6ezZs/4eNgAA6ICCDMMwLnvjoCBt2LBBycnJ5roHHnhAlZWVTc4UNTpw4IAGDx6s999/XyNHjpQkFRYW6p577tFnn32m6OhorVq1So899pg8Ho9sNpskad68edq4caMOHjwoSRo/fryqq6tVUFBg7vvmm2/W8OHDlZeXJ8MwFB0drd/+9rd65JFHJElVVVWKiIhQfn6+JkyYcMnj83q9CgsLU1VVlRwOx+VMUbvTf96mtm4hYI4sSWrrFgAArcCfz+9OgWhgy5YtCg8PV48ePfTDH/5QTz75pHr16iVJcrvd6t69uxmCJCkxMVHBwcHasWOHfvrTn8rtdmv06NFmCJIkl8ulP/zhDzp16pR69Oght9utjIwMn/d1uVxmACsvL5fH41FiYqI5HhYWpoSEBLnd7osGoZqaGtXU1JivvV5vi8wHrgzNCXmEJQCwlha/WPquu+7Sn//8ZxUXF+sPf/iDtm7dqrvvvlv19fWSJI/Ho/DwcJ9tOnXqpJ49e8rj8Zg1ERERPjWNry9Vc/74+dtdrOZCOTk5CgsLM5eYmBi/jx8AALQfLX5G6PwzLXFxcRo6dKgGDBigLVu26M4772zpt2tRWVlZPmeZvF4vYQgAgA4sIF+Nne/qq69W7969dfjwYd15552KjIzUiRMnfGrq6ur0xRdfKDIyUpIUGRmpiooKn5rG15eqOX+8cV1UVJRPzfDhwy/aq91ul91uv8wjvbJ15Gt/AAC4XAF/jtBnn32m//znP2YYcTqdqqysVElJiVnz9ttvq6GhQQkJCWbNtm3bdO7cObOmqKhI1113nXr06GHWFBcX+7xXUVGRnE6nJCk2NlaRkZE+NV6vVzt27DBrAACAtfkdhM6cOaPS0lKVlpZK+vqi5NLSUh09elRnzpzRnDlz9N577+nIkSMqLi7WT37yE11zzTVyuVySpOuvv1533XWXpk6dqp07d+pf//qXZs6cqQkTJig6OlqSNGnSJNlsNqWmpmr//v169dVXtWLFCp+vrR5++GEVFhbqqaee0sGDB7Vw4ULt2rVLM2fOlPT1HW2zZ8/Wk08+qb///e/64IMPdP/99ys6OtrnLjcAAGBdfn81tmvXLo0ZM8Z83RhOUlJStGrVKu3du1erV69WZWWloqOjNXbsWD3xxBM+XzmtWbNGM2fO1J133qng4GCNGzdOzzzzjDkeFhamN998U2lpaYqPj1fv3r2VnZ3t86yhW265RWvXrtX8+fP16KOPauDAgdq4caOGDBli1sydO1fV1dWaNm2aKisrddttt6mwsFChoaH+HjYAAOiAvtNzhDq6jvQcIa4Rah5unweA9s+fz29+awwAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFgWQQgAAFhWp7ZuALiS9J+36ZI1/EI9AHQcnBECAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWxQMVAT8156GLEg9eBID2gDNCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsvwOQtu2bdO9996r6OhoBQUFaePGjebYuXPnlJmZqbi4OHXt2lXR0dG6//77dezYMZ999O/fX0FBQT7LkiVLfGr27t2rUaNGKTQ0VDExMcrNzW3Sy/r16zVo0CCFhoYqLi5Omzdv9hk3DEPZ2dmKiopS586dlZiYqEOHDvl7yAAAoIPyOwhVV1dr2LBhWrlyZZOxL7/8Urt379bjjz+u3bt36/XXX1dZWZl+/OMfN6ldvHixjh8/bi6zZs0yx7xer8aOHat+/fqppKRES5cu1cKFC/X888+bNdu3b9fEiROVmpqqPXv2KDk5WcnJydq3b59Zk5ubq2eeeUZ5eXnasWOHunbtKpfLpbNnz/p72AAAoAMKMgzDuOyNg4K0YcMGJScnf2PN+++/r5tuukmffPKJ+vbtK+nrM0KzZ8/W7NmzL7rNqlWr9Nhjj8nj8chms0mS5s2bp40bN+rgwYOSpPHjx6u6uloFBQXmdjfffLOGDx+uvLw8GYah6Oho/fa3v9UjjzwiSaqqqlJERITy8/M1YcKESx6f1+tVWFiYqqqq5HA4mjMlV6zm/iwEWg4/sQEAbcOfz++AXyNUVVWloKAgde/e3Wf9kiVL1KtXL/3gBz/Q0qVLVVdXZ4653W6NHj3aDEGS5HK5VFZWplOnTpk1iYmJPvt0uVxyu92SpPLycnk8Hp+asLAwJSQkmDUXqqmpkdfr9VkAAEDHFdAfXT179qwyMzM1ceJEn0T2m9/8RiNGjFDPnj21fft2ZWVl6fjx41q2bJkkyePxKDY21mdfERER5liPHj3k8XjMdefXeDwes+787S5Wc6GcnBwtWrToOxwxAABoTwIWhM6dO6df/OIXMgxDq1at8hnLyMgw/zx06FDZbDb96le/Uk5Ojux2e6BauqSsrCyf3rxer2JiYtqsHwAAEFgB+WqsMQR98sknKioquuT3cwkJCaqrq9ORI0ckSZGRkaqoqPCpaXwdGRn5rTXnj5+/3cVqLmS32+VwOHwWAADQcbV4EGoMQYcOHdJbb72lXr16XXKb0tJSBQcHKzw8XJLkdDq1bds2nTt3zqwpKirSddddpx49epg1xcXFPvspKiqS0+mUJMXGxioyMtKnxuv1aseOHWYNAACwNr+/Gjtz5owOHz5svi4vL1dpaal69uypqKgo/fznP9fu3btVUFCg+vp683qcnj17ymazye12a8eOHRozZoy6desmt9ut9PR0/fKXvzRDzqRJk7Ro0SKlpqYqMzNT+/bt04oVK/T000+b7/vwww/r9ttv11NPPaWkpCStW7dOu3btMm+xDwoK0uzZs/Xkk09q4MCBio2N1eOPP67o6OhvvcsNAABYh9+3z2/ZskVjxoxpsj4lJUULFy5scpFzo3feeUd33HGHdu/erV//+tc6ePCgampqFBsbq8mTJysjI8Pn+qC9e/cqLS1N77//vnr37q1Zs2YpMzPTZ5/r16/X/PnzdeTIEQ0cOFC5ubm65557zHHDMLRgwQI9//zzqqys1G233abnnntO1157bbOOldvn8V1w+zwAtA1/Pr+/03OEOjqCEL4LghAAtI0r6jlCAAAAVyqCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCyCEAAAsCy/f30eQPM05/fd+D0yAGhbnBECAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWRRACAACWxU9sAG2In+EAgLbFGSEAAGBZBCEAAGBZBCEAAGBZBCEAAGBZBCEAAGBZBCEAAGBZBCEAAGBZBCEAAGBZfgehbdu26d5771V0dLSCgoK0ceNGn3HDMJSdna2oqCh17txZiYmJOnTokE/NF198ofvuu08Oh0Pdu3dXamqqzpw541Ozd+9ejRo1SqGhoYqJiVFubm6TXtavX69BgwYpNDRUcXFx2rx5s9+9AAAA6/I7CFVXV2vYsGFauXLlRcdzc3P1zDPPKC8vTzt27FDXrl3lcrl09uxZs+a+++7T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uQLYmWHw1VgA1NbWqqSkRImJiea64OBgJSYmyu12X3Qbt9vtUy9JLpfrG+txefN8oS+//FLnzp1Tz549A9Vmu3e587x48WKFh4crNTW1Ndps9y5nnv/+97/L6XQqLS1NERERGjJkiH7/+9+rvr6+tdpudy5nnm+55RaVlJSYX599/PHH2rx5s+65555W6dkq2upzsMM/WbotfP7556qvr2/y9OqIiAgdPHjwott4PJ6L1ns8noD12d5dzjxfKDMzU9HR0U3+5cP/uZx5fvfdd/XSSy+ptLS0FTrsGC5nnj/++GO9/fbbuu+++7R582YdPnxYv/71r3Xu3DktWLCgNdpudy5nnidNmqTPP/9ct912mwzDUF1dnaZPn65HH320NVq2jG/6HPR6vfrqq6/UuXPngLwvZ4RgWUuWLNG6deu0YcMGhYaGtnU7Hcbp06c1efJkvfDCC+rdu3dbt9OhNTQ0KDw8XM8//7zi4+M1fvx4PfbYY8rLy2vr1jqULVu26Pe//72ee+457d69W6+//ro2bdqkJ554oq1bQwvgjFAA9O7dWyEhIaqoqPBZX1FRocjIyItuExkZ6Vc9Lm+eG/3xj3/UkiVL9NZbb2no0KGBbLPd83eeP/roIx05ckT33nuvua6hoUGS1KlTJ5WVlWnAgAGBbbodupx/nqOionTVVVcpJCTEXHf99dfL4/GotrZWNpstoD23R5czz48//rgmT56shx56SJIUFxen6upqTZs2TY899piCgzmn0BK+6XPQ4XAE7GyQxBmhgLDZbIqPj1dxcbG5rqGhQcXFxXI6nRfdxul0+tRLUlFR0TfW4/LmWZJyc3P1xBNPqLCwUCNHjmyNVts1f+d50KBB+uCDD1RaWmouP/7xjzVmzBiVlpYqJiamNdtvNy7nn+dbb71Vhw8fNoOmJP3v//6voqKiCEHf4HLm+csvv2wSdhrDp8HPdbaYNvscDOil2Ba2bt06w263G/n5+caHH35oTJs2zejevbvh8XgMwzCMyZMnG/PmzTPr//WvfxmdOnUy/vjHPxoHDhwwFixYwO3zzeDvPC9ZssSw2WzGf//3fxvHjx83l9OnT7fVIbQL/s7zhbhrrHn8neejR48a3bp1M2bOnGmUlZUZBQUFRnh4uPHkk0+21SG0C/7O84IFC4xu3boZf/3rX42PP/7YePPNN40BAwYYv/jFL9rqENqF06dPG3v27DH27NljSDKWLVtm7Nmzx/jkk08MwzCMefPmGZMnTzbrG2+fnzNnjnHgwAFj5cqV3D7f3v3pT38y+vbta9hsNuOmm24y3nvvPXPs9ttvN1JSUnzqX3vtNePaa681bDabccMNNxibNm1q5Y7bJ3/muV+/foakJsuCBQtav/F2xt9/ns9HEGo+f+d5+/btRkJCgmG3242rr77a+N3vfmfU1dW1ctftjz/zfO7cOWPhwoXGgAEDjNDQUCMmJsb49a9/bZw6dar1G29H3nnnnYv+fds4tykpKcbtt9/eZJvhw4cbNpvNuPrqq41XXnkl4H0GGQbn9QAAgDVxjRAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALAsghAAALCs/w9z0H7VRUQ3fAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(total_infos_2.values(), bins=np.linspace(0, 1, 50))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "097e26a4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-12T22:41:30.694878Z",
     "start_time": "2024-01-12T22:41:30.692934Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:14.001267Z",
     "iopub.status.busy": "2025-04-22T00:54:14.001112Z",
     "iopub.status.idle": "2025-04-22T00:54:14.003816Z",
     "shell.execute_reply": "2025-04-22T00:54:14.003414Z",
     "shell.execute_reply.started": "2025-04-22T00:54:14.001252Z"
    }
   },
   "outputs": [],
   "source": [
    "# sub_total_infos = {k: v for k, v in total_infos.items() if k in total_infos_2}\n",
    "\n",
    "# len(sub_total_infos)\n",
    "\n",
    "# plt.hist(sub_total_infos.values(), bins=np.linspace(0, 1, 50))\n",
    "# plt.show()\n",
    "\n",
    "# np.median(list(sub_total_infos.values())), np.median(list(total_infos_2.values()))\n",
    "\n",
    "# interesting_diffs = []\n",
    "# for k in total_infos_2:\n",
    "#     if k in sub_total_infos and total_infos_2[k] - sub_total_infos[k] < 0.3 and sub_total_infos[k] > 0.6:\n",
    "#         interesting_diffs.append(k)\n",
    "# print(len(interesting_diffs))\n",
    "\n",
    "# for idx in interesting_diffs:\n",
    "#     if idx in metas_map and metas_map[idx][\"lang\"] == \"zh\":\n",
    "#         print(metas_map[idx])\n",
    "#         break"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42dcbcc8",
   "metadata": {},
   "source": [
    "# prepare the 2nd hoot dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "326e1b84",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:49:58.544826Z",
     "start_time": "2024-01-15T18:49:56.487590Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:54:14.004400Z",
     "iopub.status.busy": "2025-04-22T00:54:14.004272Z",
     "iopub.status.idle": "2025-04-22T00:54:16.823629Z",
     "shell.execute_reply": "2025-04-22T00:54:16.823053Z",
     "shell.execute_reply.started": "2025-04-22T00:54:14.004387Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "932872\n"
     ]
    }
   ],
   "source": [
    "high_cer_infos_2 = {}\n",
    "for k, v in total_infos_2.items():\n",
    "    k_lang = metas_map[k][\"lang\"]\n",
    "    # should probably also play it safe\n",
    "    # tigher cut\n",
    "    cut_threshold = min(langs_cer_cut.get(k_lang, 0.5), 0.5)\n",
    "    # looser cut\n",
    "    # cut_threshold = min(langs_cer_cut.get(k_lang, 0.7), 0.7)\n",
    "    if v <= cut_threshold:\n",
    "        high_cer_infos_2[k] = v\n",
    "print(len(high_cer_infos_2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "636c3311",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:51:44.029594Z",
     "start_time": "2024-01-15T18:51:42.398978Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:56:13.272833Z",
     "iopub.status.busy": "2025-04-22T00:56:13.272404Z",
     "iopub.status.idle": "2025-04-22T00:56:14.524912Z",
     "shell.execute_reply": "2025-04-22T00:56:14.524343Z",
     "shell.execute_reply.started": "2025-04-22T00:56:13.272814Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "914940 1786.9921875\n"
     ]
    }
   ],
   "source": [
    "high_cer_train_info_2 = []\n",
    "for info in train_info:\n",
    "    if (\n",
    "        info[\"id\"] in high_cer_infos_2 and info[\"duration\"] < 300\n",
    "    ):  # --> this is how v3 t9 data is prepared\n",
    "        # if info[\"id\"] in high_cer_infos_2 and 210 < info[\"duration\"] < 300:\n",
    "        high_cer_train_info_2.append(info)\n",
    "print(len(high_cer_train_info_2), len(high_cer_train_info_2) / 4 / 8 / 16)\n",
    "# tigher cut\n",
    "# 914940 1786.9921875\n",
    "# total duration khr 50.24248\n",
    "# looser cut\n",
    "# 1509511 11793.0546875\n",
    "# total duration khr 82.92342055555555, "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "bf451a42",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:52:00.685027Z",
     "start_time": "2024-01-15T18:51:59.480509Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:56:14.525840Z",
     "iopub.status.busy": "2025-04-22T00:56:14.525683Z",
     "iopub.status.idle": "2025-04-22T00:56:16.229240Z",
     "shell.execute_reply": "2025-04-22T00:56:16.228700Z",
     "shell.execute_reply.started": "2025-04-22T00:56:14.525824Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total duration khr 50.24248, \n",
      "    min duration 60, \n",
      "    max duration 299, \n",
      "    min text len 21, \n",
      "    max text len 6213\n",
      "\n",
      "Counter({'en': 556176, 'es': 72985, 'pt': 38989, 'fr': 38832, 'de': 33173, 'it': 25071, 'ru': 22736, 'pl': 18637, 'ko': 14980, 'ja': 12294, 'tr': 11371, 'nl': 4891, 'ar': 4009, 'id': 3915, 'iw': 3447, 'el': 3283, 'sv': 3195, 'ro': 3176, 'da': 2759, 'hi': 2571, 'fi': 2463, 'sr': 2375, 'cs': 2256, 'zh': 2200, 'tl': 2124, 'hr': 2098, 'no': 1878, 'pa': 1702, 'hu': 1685, 'vi': 1492, 'th': 1253, 'fa': 1200, 'az': 1119, 'sk': 1077, 'romanization': 1039, 'zh-Hant': 984, 'uk': 925, 'bs': 897, 'bg': 668, 'sq': 611, 'af': 609, 'ca': 567, 'et': 543, 'he': 510, 'ms': 475, 'lv': 448, 'lt': 376, 'sl': 370, 'bn': 303, 'eu': 290, 'sw': 287, 'is': 262, 'ne': 204, 'mk': 180, 'gl': 170, 'ta': 160, 'ht': 153, 'co': 141, 'la': 141, 'mr': 136, 'eo': 130, 'sco': 128, 'zu': 117, 'ka': 86, 'xh': 69, 'am': 66, 'war': 65, 'als': 64, 'hy': 63, 'ceb': 61, 'nn': 60, 'yo': 52, 'cy': 48, 'sn': 46, 'kk': 44, 'arz': 43, 'uz': 40, 'be': 38, 'su': 38, 'rw': 37, 'ku': 34, 'jv': 32, 'lb': 31, 'sh': 30, 'ak': 28, 'ln': 24, 'jw': 23, 'sa': 23, 'ky': 22, 'oc': 21, 'ga': 20, 'rm': 19, 'st': 17, 'ia': 17, 'mg': 17, 'as': 17, 'gd': 16, 'qu': 16, 'bh': 15, 'br': 15, 'nap': 14, 'tk': 13, 'sm': 13, 'ny': 13, 'aa': 12, 'mi': 12, 'gn': 11, 'ha': 11, 'wo': 11, 'lg': 10, 'fo': 10, 'nds': 10, 'ie': 9, 'mn': 9, 'ast': 8, 'tlh': 7, 'fy': 7, 'si': 7, 'ig': 7, 'ur': 7, 'jbo': 7, 'kw': 7, 'bi': 6, 'to': 6, 'my': 6, 'tn': 6, 'tt': 5, 'ss': 5, 'so': 5, 'vo': 5, 'mt': 5, 'crs': 5, 'yi': 5, 'rn': 4, 'km': 4, 'haw': 4, 'mfe': 4, 'vec': 4, 'io': 4, 'lmo': 4, 'min': 4, 'kn': 3, 'ts': 3, 'gu': 3, 'gv': 2, 'tg': 2, 'om': 2, 've': 2, 'pms': 2, 'diq': 2, 'ckb': 2, 'ay': 1, 'fj': 1, 'hmn': 1, 'iu': 1, 'kha': 1, 'na': 1, 'wa': 1, 'ml': 1, 'eml': 1, 'bcl': 1, 'ba': 1, 'sc': 1, 'scn': 1, 'new': 1, 'gom': 1, 'azb': 1, 'pam': 1, 'li': 1})\n"
     ]
    }
   ],
   "source": [
    "print(\n",
    "    f\"\"\"total duration khr {sum(m['duration'] for m in high_cer_train_info_2) / 3600000}, \n",
    "    min duration {min(m['duration'] for m in high_cer_train_info_2)}, \n",
    "    max duration {max(m['duration'] for m in high_cer_train_info_2)}, \n",
    "    min text len {min(len(m['text']) for m in high_cer_train_info_2)}, \n",
    "    max text len {max(len(m['text']) for m in high_cer_train_info_2)}\n",
    "\"\"\"\n",
    ")\n",
    "print(Counter(m[\"lang\"] for m in high_cer_train_info_2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "063513d5-ddf4-47c5-aa3c-6382d63f35e2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:58:21.268799Z",
     "iopub.status.busy": "2025-04-22T00:58:21.268359Z",
     "iopub.status.idle": "2025-04-22T00:58:26.146266Z",
     "shell.execute_reply": "2025-04-22T00:58:26.145707Z",
     "shell.execute_reply.started": "2025-04-22T00:58:21.268779Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3870\n",
      "3000\n"
     ]
    }
   ],
   "source": [
    "selected_multi_validation_set = read_jsonl(\n",
    "    \"/home/tony/Data/Hoot/v4_multi_validation_set.json\"\n",
    ")\n",
    "print(len(selected_multi_validation_set))\n",
    "selected_en_validation_set = read_jsonl(\n",
    "    \"/home/tony/Data/Hoot/v4_en_validation_set.json\"\n",
    ")\n",
    "print(len(selected_en_validation_set))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "26c6eac1-736a-4f93-9a19-40e1c0152dc5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:58:27.052444Z",
     "iopub.status.busy": "2025-04-22T00:58:27.052277Z",
     "iopub.status.idle": "2025-04-22T00:58:27.056534Z",
     "shell.execute_reply": "2025-04-22T00:58:27.056062Z",
     "shell.execute_reply.started": "2025-04-22T00:58:27.052429Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6870\n"
     ]
    }
   ],
   "source": [
    "selected_validation_set_ids = set(x[\"id\"] for x in selected_multi_validation_set).union(\n",
    "    set(x[\"id\"] for x in selected_en_validation_set)\n",
    ")\n",
    "print(len(selected_validation_set_ids))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "5492f723-0ac1-45bd-8539-bfd093a5335b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:58:28.209121Z",
     "iopub.status.busy": "2025-04-22T00:58:28.208968Z",
     "iopub.status.idle": "2025-04-22T00:58:28.497070Z",
     "shell.execute_reply": "2025-04-22T00:58:28.496606Z",
     "shell.execute_reply.started": "2025-04-22T00:58:28.209107Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "914940\n",
      "911627\n"
     ]
    }
   ],
   "source": [
    "print(len(high_cer_train_info_2))\n",
    "high_cer_train_info_2 = [\n",
    "    x for x in high_cer_train_info_2 if x[\"id\"] not in selected_validation_set_ids\n",
    "]\n",
    "print(len(high_cer_train_info_2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "90466614",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:52:12.098221Z",
     "start_time": "2024-01-15T18:52:11.939584Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:58:29.531711Z",
     "iopub.status.busy": "2025-04-22T00:58:29.531567Z",
     "iopub.status.idle": "2025-04-22T00:58:29.894215Z",
     "shell.execute_reply": "2025-04-22T00:58:29.893745Z",
     "shell.execute_reply.started": "2025-04-22T00:58:29.531696Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "907627 4000\n"
     ]
    }
   ],
   "source": [
    "cutoff = -4000\n",
    "random.shuffle(high_cer_train_info_2)\n",
    "high_cer_train_info_2, high_cer_test_info_2 = (\n",
    "    high_cer_train_info_2[:cutoff],\n",
    "    high_cer_train_info_2[cutoff:],\n",
    ")\n",
    "print(len(high_cer_train_info_2), len(high_cer_test_info_2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "74ef0ed9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:52:34.087188Z",
     "start_time": "2024-01-15T18:52:23.399643Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:58:40.180463Z",
     "iopub.status.busy": "2025-04-22T00:58:40.180031Z",
     "iopub.status.idle": "2025-04-22T00:59:03.991205Z",
     "shell.execute_reply": "2025-04-22T00:59:03.990488Z",
     "shell.execute_reply.started": "2025-04-22T00:58:40.180443Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/v6_t1_cer_30_long_train.json\", \"w\") as fp:\n",
    "#     for l in high_cer_train_info_2:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')\n",
    "# with open(\"/home/tony/Data/Hoot/v6_t1_cer_30_long_test.json\", \"w\") as fp:\n",
    "#     for l in high_cer_test_info_2:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write('\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "61409fbd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-15T18:52:34.091372Z",
     "start_time": "2024-01-15T18:52:34.089444Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:03.992636Z",
     "iopub.status.busy": "2025-04-22T00:59:03.992333Z",
     "iopub.status.idle": "2025-04-22T00:59:03.995751Z",
     "shell.execute_reply": "2025-04-22T00:59:03.995210Z",
     "shell.execute_reply.started": "2025-04-22T00:59:03.992619Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Done\n"
     ]
    }
   ],
   "source": [
    "print(\"Done\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "535130a0",
   "metadata": {},
   "source": [
    "# Curate a seperate list of long audios, for just evaluation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "13fa3abf",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-11T19:10:11.366040Z",
     "start_time": "2024-01-11T19:10:10.100230Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:03.996570Z",
     "iopub.status.busy": "2025-04-22T00:59:03.996428Z",
     "iopub.status.idle": "2025-04-22T00:59:05.748174Z",
     "shell.execute_reply": "2025-04-22T00:59:05.747426Z",
     "shell.execute_reply.started": "2025-04-22T00:59:03.996556Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "914940\n"
     ]
    }
   ],
   "source": [
    "high_cer_train_info_2_long = []\n",
    "for info in train_info:\n",
    "    if info[\"id\"] in high_cer_infos_2 and info[\"duration\"] < 300:\n",
    "        high_cer_train_info_2_long.append(info)\n",
    "print(len(high_cer_train_info_2_long))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "5c7f0742",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-11T19:10:11.424285Z",
     "start_time": "2024-01-11T19:10:11.367473Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:05.750034Z",
     "iopub.status.busy": "2025-04-22T00:59:05.749478Z",
     "iopub.status.idle": "2025-04-22T00:59:06.169419Z",
     "shell.execute_reply": "2025-04-22T00:59:06.168767Z",
     "shell.execute_reply.started": "2025-04-22T00:59:05.750015Z"
    }
   },
   "outputs": [],
   "source": [
    "random.shuffle(high_cer_train_info_2_long)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "cfbf0a99",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-11T19:10:12.582481Z",
     "start_time": "2024-01-11T19:10:12.457526Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:06.170232Z",
     "iopub.status.busy": "2025-04-22T00:59:06.170073Z",
     "iopub.status.idle": "2025-04-22T00:59:07.330394Z",
     "shell.execute_reply": "2025-04-22T00:59:07.329706Z",
     "shell.execute_reply.started": "2025-04-22T00:59:06.170216Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4617\n"
     ]
    }
   ],
   "source": [
    "selected_validation_set = []\n",
    "c = Counter()\n",
    "for m in high_cer_train_info_2_long:\n",
    "    if c[m[\"lang\"]] < min(len(lang_cers.get(m[\"lang\"], [])) // 4, 50):\n",
    "        selected_validation_set.append(m)\n",
    "        c[m[\"lang\"]] += 1\n",
    "print(len(selected_validation_set))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "d3c6afd4-c44a-495d-b311-bb8042a9bfe1",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:07.331579Z",
     "iopub.status.busy": "2025-04-22T00:59:07.331116Z",
     "iopub.status.idle": "2025-04-22T00:59:07.333739Z",
     "shell.execute_reply": "2025-04-22T00:59:07.333237Z",
     "shell.execute_reply.started": "2025-04-22T00:59:07.331561Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/v4_multi_validation_set.json\", \"w\") as fp:\n",
    "#     for l in selected_validation_set:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write(\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "f8d88911",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-11T19:10:43.816910Z",
     "start_time": "2024-01-11T19:10:43.660712Z"
    },
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:07.334550Z",
     "iopub.status.busy": "2025-04-22T00:59:07.334284Z",
     "iopub.status.idle": "2025-04-22T00:59:08.312347Z",
     "shell.execute_reply": "2025-04-22T00:59:08.311712Z",
     "shell.execute_reply.started": "2025-04-22T00:59:07.334537Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3000\n"
     ]
    }
   ],
   "source": [
    "selected_validation_set_ids = set(x[\"id\"] for x in selected_validation_set)\n",
    "selected_en_validation_set = []\n",
    "c = Counter()\n",
    "for m in high_cer_train_info_2_long:\n",
    "    if (\n",
    "        m[\"lang\"] == \"en\"\n",
    "        and m[\"id\"] not in selected_validation_set_ids\n",
    "        and c[m[\"lang\"]] < 3000\n",
    "    ):\n",
    "        selected_en_validation_set.append(m)\n",
    "        c[m[\"lang\"]] += 1\n",
    "print(len(selected_en_validation_set))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "c1e7ac97",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-04-22T00:59:08.313334Z",
     "iopub.status.busy": "2025-04-22T00:59:08.312987Z",
     "iopub.status.idle": "2025-04-22T00:59:08.315407Z",
     "shell.execute_reply": "2025-04-22T00:59:08.314928Z",
     "shell.execute_reply.started": "2025-04-22T00:59:08.313318Z"
    }
   },
   "outputs": [],
   "source": [
    "# with open(\"/home/tony/Data/Hoot/v4_en_validation_set.json\", \"w\") as fp:\n",
    "#     for l in selected_en_validation_set:\n",
    "#         json.dump(l, fp, ensure_ascii=True)\n",
    "#         fp.write(\"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2854610a",
   "metadata": {},
   "source": [
    "# Validations and checks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "id": "a0e31899-aeca-457d-bafa-c313f22180b7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-22T01:17:50.188057Z",
     "iopub.status.busy": "2025-02-22T01:17:50.187929Z",
     "iopub.status.idle": "2025-02-22T01:17:50.230931Z",
     "shell.execute_reply": "2025-02-22T01:17:50.230546Z",
     "shell.execute_reply.started": "2025-02-22T01:17:50.188044Z"
    }
   },
   "outputs": [],
   "source": [
    "# train_infos = read_jsonl(\"/home/tony/Data/Hoot/v5_t1_cer_66_long_train.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "id": "094c8548",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-22T01:17:50.231498Z",
     "iopub.status.busy": "2025-02-22T01:17:50.231367Z",
     "iopub.status.idle": "2025-02-22T01:17:50.266466Z",
     "shell.execute_reply": "2025-02-22T01:17:50.266082Z",
     "shell.execute_reply.started": "2025-02-22T01:17:50.231484Z"
    }
   },
   "outputs": [],
   "source": [
    "# print(len(train_infos))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 199,
   "id": "df1ffb98",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-22T01:17:50.267038Z",
     "iopub.status.busy": "2025-02-22T01:17:50.266916Z",
     "iopub.status.idle": "2025-02-22T01:17:50.303498Z",
     "shell.execute_reply": "2025-02-22T01:17:50.303106Z",
     "shell.execute_reply.started": "2025-02-22T01:17:50.267025Z"
    }
   },
   "outputs": [],
   "source": [
    "# # with open(\"tmp/genius_hq_silent_80_ids.txt\", \"r\") as fp:\n",
    "# #     ids = set(fp.read().splitlines())\n",
    "# # print(len(ids))\n",
    "# # n_silent_in_train = 0\n",
    "# for curr_train_info in train_infos:\n",
    "#     if curr_train_info[\"lang\"] == \"hi\":\n",
    "#         print(curr_train_info)\n",
    "#         print(curr_train_info[\"lyrics\"])\n",
    "#         break\n",
    "# #     if curr_train_info[\"id\"] in ids:\n",
    "# #         n_silent_in_train += 1\n",
    "# #         print(curr_train_info)\n",
    "# # print(n_silent_in_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 200,
   "id": "755afe1f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-22T01:17:50.304227Z",
     "iopub.status.busy": "2025-02-22T01:17:50.304099Z",
     "iopub.status.idle": "2025-02-22T01:17:50.449092Z",
     "shell.execute_reply": "2025-02-22T01:17:50.448598Z",
     "shell.execute_reply.started": "2025-02-22T01:17:50.304214Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/tony/anaconda3/envs/suno_env_dev/lib/python3.10/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "from hoot.model import Tokenizer\n",
    "gpt_tokenizer = Tokenizer(filepath=\"/app/suno/data/dpo/models/tokenizer_60k.json\")\n",
    "print(gpt_tokenizer.encode(\"piano concerto\"))\n",
    "print(gpt_tokenizer.encode(\"Piano\"), gpt_tokenizer.encode(\"piano\"))\n",
    "print(gpt_tokenizer.encode(\"Harmonica\"), gpt_tokenizer.encode(\"harmonica\"))\n",
    "print(gpt_tokenizer.encode(\"Male\"), gpt_tokenizer.encode(\"male\"), gpt_tokenizer.encode(\"MALE\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b56e9cd-f7e5-40a4-8af9-ffce20838d4b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "suno_env_dev",
   "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.10.15"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
