{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "21cff283-e594-4c76-ac85-b4360833c345",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import torch\n",
    "import tqdm"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71aeaa37-7924-4c9e-9005-65caa6058166",
   "metadata": {},
   "source": [
    "## Prepare and Save LibriSpeech trancription logits using a pretrained speech model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "33c4cfaf-c0a7-40cf-8f2e-ee86d2fa5f61",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import torchaudio\n",
    "# bundle = torchaudio.pipelines.WAV2VEC2_ASR_BASE_100H\n",
    "# asr_model = bundle.get_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1ea0e685",
   "metadata": {},
   "outputs": [],
   "source": [
    "# librispeech_path = \"/mnt/data-ssd-1/data/librispeech_tmp\"\n",
    "# dataset = torchaudio.datasets.LIBRISPEECH(librispeech_path, url=\"dev-other\", download=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "adefa343-1e3f-4e3d-a6bb-ca51b9c8c55c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# logits_torch = []\n",
    "# transcription = []\n",
    "# for idx, sample in tqdm.tqdm(enumerate(dataset), total=len(dataset)):\n",
    "#     waveform, _, transcript, _, _, _ = sample\n",
    "#     transcript = transcript.strip().lower().strip()\n",
    "    \n",
    "#     with torch.inference_mode():\n",
    "#         emission, _ = asr_model(waveform)\n",
    "    \n",
    "#     logits_torch.append(emission)\n",
    "#     transcription.append(transcript)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "da587776-0a72-43b8-a267-bfa7476ff16a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# tokens = list(bundle.get_labels())\n",
    "# tokens = [t.lower() for t in tokens]\n",
    "# pyctc_tokens = [\"_\"] + tokens[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "215592e3-9892-45d7-a5c5-68c522deb276",
   "metadata": {},
   "outputs": [],
   "source": [
    "# torch.save(logits_torch, \"w2v2/logits.pt\")\n",
    "# torch.save(transcription, \"w2v2/transcripts.pt\")\n",
    "# torch.save(pyctc_tokens, \"w2v2/pyctc_tokens.pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c10bba3-695e-49f3-aefd-7853600875b8",
   "metadata": {},
   "source": [
    "## Prepare tokens, lexicon, 3-gram language model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "da4def53-ddbd-4de3-b5e6-1af29b228362",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "def softmax(logits):\n",
    "    e = np.exp(logits - np.max(logits))\n",
    "    return e / e.sum(axis=-1).reshape([logits.shape[0], 1])\n",
    "\n",
    "logits_torch = torch.load(\"w2v2/logits.pt\")\n",
    "logits_numpy = [logits.squeeze(dim=0).cpu().detach().numpy() for logits in logits_torch]\n",
    "\n",
    "logits_softmax = [softmax(logits) for logits in logits_numpy]\n",
    "logits_nemo = [np.concatenate((logits[:, 1:], logits[:, 0:1]), axis=1) for logits in logits_softmax]\n",
    "logits_nemo = [np.expand_dims(logits, axis=0) for logits in logits_nemo]\n",
    "\n",
    "transcription = torch.load(\"w2v2/transcripts.pt\")\n",
    "pyctc_tokens = torch.load(\"w2v2/pyctc_tokens.pt\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "254b54b9-6674-4ecd-bce7-ec300b9f7f03",
   "metadata": {},
   "outputs": [],
   "source": [
    "from torchaudio.models.decoder import ctc_decoder, download_pretrained_files\n",
    "files = download_pretrained_files(\"librispeech-3-gram\")\n",
    "kenlm_file = files.lm\n",
    "lexicon_file = files.lexicon\n",
    "tokens_file = files.tokens\n",
    "\n",
    "lexicon_list = []\n",
    "with open(lexicon_file) as f:\n",
    "    for line in f:\n",
    "        lexicon_list.append(line.split()[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14c716b8-a2fb-4735-a228-4cfd92b0bbb0",
   "metadata": {},
   "source": [
    "## Eval Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9c898161-3a2d-438c-80d6-b830f03aa81d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[NeMo W 2022-10-25 14:32:02 optimizers:67] Could not import distributed_fused_adam optimizer from Apex\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "import multiprocessing\n",
    "from nemo.collections.asr.metrics.wer import word_error_rate\n",
    "\n",
    "num_samples = 500\n",
    "beam_widths = [1, 5, 10, 50, 100, 150]\n",
    "\n",
    "def create_df(data):\n",
    "    return pd.DataFrame(data, columns=['wer_val', 'avg_dur_ms', 'beam_width'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4224894-838a-465d-bc6c-c3ae50dcd5b6",
   "metadata": {},
   "source": [
    "## Eval pyctcdecode decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "48ad3deb-6f5c-4180-add4-9f3e51598efb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from pyctcdecode import build_ctcdecoder\n",
    "from suno_utils.ctcdecode.decoder import build_ctcdecoder\n",
    "\n",
    "decoder = build_ctcdecoder(\n",
    "    pyctc_tokens,\n",
    "    kenlm_file,\n",
    "#     unigrams,\n",
    "#     lexicon_list,\n",
    "    alpha=0.8,  # 0.5\n",
    "    beta=2.0,  # 1.5\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "7d3f229e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# def greedy_decode(logits):\n",
    "#     pt = None\n",
    "#     l = []\n",
    "#     for n in logits.argmax(1):\n",
    "#         t = pyctc_tokens[n]\n",
    "#         if t != pt:\n",
    "#             l.append(t)\n",
    "#         pt = t\n",
    "#     return \"\".join(l).replace(\"_\", \"\").replace(\"|\", \" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4d4fd6d9-6cec-4398-857f-7b431641af0d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # perform grid search according to pyctcdecode library\n",
    "# data_grid = []\n",
    "# for a in [0.7, 0.8, 1]:\n",
    "#     for b in [0, 1.0, 2.0]:\n",
    "#         decoder.reset_params(alpha=a, beta=b)\n",
    "#         pred_list = [decoder.decode(logits) for logits in logits_numpy[:num_samples]]\n",
    "#         wer_val = word_error_rate(transcription[:num_samples], pred_list)\n",
    "#         data_grid.append((a, b, wer_val))\n",
    "#         print((a, b, wer_val))\n",
    "# pd.DataFrame(data_grid, columns=[\"alpha\", \"beta\", \"wer\"]).sort_values(by=\"wer\").head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ec337f70",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " 25%|████████████████████████████████████████████                                                                                                                                    | 1/4 [00:01<00:04,  1.62s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(19.275579651632253, 3.2, 1)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\r",
      " 50%|████████████████████████████████████████████████████████████████████████████████████████                                                                                        | 2/4 [00:06<00:07,  3.75s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(15.36039188243527, 10.5, 5)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\r",
      " 75%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████                                            | 3/4 [00:15<00:06,  6.02s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(14.29068553532073, 17.4, 10)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:43<00:00, 10.87s/it]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(12.465533088235293, 55.8, 50)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>wer_val</th>\n",
       "      <th>avg_dur_ms</th>\n",
       "      <th>beam_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>19.275580</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>15.360392</td>\n",
       "      <td>10.5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>14.290686</td>\n",
       "      <td>17.4</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>12.465533</td>\n",
       "      <td>55.8</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     wer_val  avg_dur_ms  beam_width\n",
       "0  19.275580         3.2           1\n",
       "1  15.360392        10.5           5\n",
       "2  14.290686        17.4          10\n",
       "3  12.465533        55.8          50"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_pyctc = []\n",
    "# for beam_width in tqdm.tqdm(beam_widths + [500, 2000]):\n",
    "for beam_width in tqdm.tqdm(beam_widths[:-2]):# + [500, 2000]):\n",
    "    t0 = time.time()\n",
    "    pred_list = [\n",
    "        decoder.decode(\n",
    "            logits, \n",
    "            beam_width=beam_width,\n",
    "            beam_prune_logp=-20,\n",
    "            token_min_logp=-7,\n",
    "        ) \n",
    "        for logits in logits_numpy[:num_samples]\n",
    "    ]\n",
    "    dur = round((time.time() - t0) / num_samples * 1000, 1)\n",
    "    wer_val = word_error_rate(transcription[:num_samples], pred_list)\n",
    "    data_pyctc.append((wer_val * 100, dur, beam_width))\n",
    "    print((wer_val * 100, dur, beam_width))\n",
    "df_pyctc = create_df(data_pyctc)\n",
    "df_pyctc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "32aaef16",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # \twer_val\tavg_dur_ms\tbeam_width\n",
    "# 0\t19.275580\t3.3\t1\n",
    "# 1\t15.360392\t10.5\t5\n",
    "# 2\t14.290686\t17.4\t10\n",
    "# 3\t12.465533\t55.6\t50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd6cb545",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16ccd8f2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df04cf2e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c49cf90",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "c154d7db-5baf-412c-b1d7-df093b723bec",
   "metadata": {},
   "source": [
    "## Eval torchaudio decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "id": "7371ffea-05fd-48a1-a47c-3f8f5e480f08",
   "metadata": {},
   "outputs": [],
   "source": [
    "from torchaudio.models.decoder import ctc_decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "id": "49b2638e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 8/8 [01:53<00:00, 14.18s/it]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>wer_val</th>\n",
       "      <th>avg_dur_ms</th>\n",
       "      <th>beam_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37.204536</td>\n",
       "      <td>0.5</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>15.429437</td>\n",
       "      <td>1.1</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>14.231037</td>\n",
       "      <td>1.7</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>12.712551</td>\n",
       "      <td>4.1</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>12.299156</td>\n",
       "      <td>6.2</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>12.273200</td>\n",
       "      <td>7.9</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>12.062392</td>\n",
       "      <td>15.9</td>\n",
       "      <td>500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>11.931162</td>\n",
       "      <td>31.0</td>\n",
       "      <td>2000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     wer_val  avg_dur_ms  beam_width\n",
       "0  37.204536         0.5           1\n",
       "1  15.429437         1.1           5\n",
       "2  14.231037         1.7          10\n",
       "3  12.712551         4.1          50\n",
       "4  12.299156         6.2         100\n",
       "5  12.273200         7.9         150\n",
       "6  12.062392        15.9         500\n",
       "7  11.931162        31.0        2000"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sweep beam_width for torchaudio decoder\n",
    "data_torch = []\n",
    "for beam_width in tqdm.tqdm(beam_widths + [500, 2000]):\n",
    "    torch_decoder = ctc_decoder(\n",
    "        lexicon=lexicon_file,\n",
    "        tokens=tokens_file,\n",
    "        lm=kenlm_file,\n",
    "        beam_size=beam_width,\n",
    "        beam_threshold=10,\n",
    "    )\n",
    "    \n",
    "    pred_list = [\" \".join(torch_decoder(logits)[0][0].words) for logits in logits_torch[:num_samples]]\n",
    "    wer_val = word_error_rate(transcription[:num_samples], pred_list)\n",
    "    \n",
    "    t0 = time.time()\n",
    "    _ = [torch_decoder(logits) for logits in logits_torch[:num_samples]]\n",
    "    dur = round((time.time() - t0) / num_samples * 1000, 1)\n",
    "    data_torch.append((wer_val * 100, dur, beam_width))\n",
    "    \n",
    "df_torch = create_df(data_torch)\n",
    "df_torch"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "666d6ac4-296a-45d2-aebd-f0886e8234a2",
   "metadata": {},
   "source": [
    "## Eval Nemo Decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "afe64f21-8b92-4ba7-9379-119c34f81627",
   "metadata": {},
   "outputs": [],
   "source": [
    "from nemo.collections.asr.modules import BeamSearchDecoderWithLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "90590a08-1fe2-40ad-8ca4-07ed75d10097",
   "metadata": {},
   "outputs": [],
   "source": [
    "nemo_tokens = pyctc_tokens[1:]\n",
    "nemo_tokens[0] = \" \""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2d899bd1-6244-4650-b818-6474a82b924d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # perform grid search according to pyctcdecode library\n",
    "# data_grid = []\n",
    "# for a in [0.5, 1, 1.5]:\n",
    "#     for b in [0, 1.0, 2.0]:\n",
    "#         nemo_decoder = BeamSearchDecoderWithLM(\n",
    "#             vocab=list(nemo_tokens),\n",
    "#             beam_width=10,\n",
    "#             alpha=a,\n",
    "#             beta=b,\n",
    "#             lm_path=kenlm_file,\n",
    "#             num_cpus=1,\n",
    "#             input_tensor=False,\n",
    "#         )\n",
    "#         pred_list = [nemo_decoder.forward(log_probs=logits, log_probs_length=None,)[0][0][1] for logits in logits_nemo[:num_samples]]\n",
    "#         wer_val = word_error_rate(transcription[:num_samples], pred_list)\n",
    "#         data_grid.append((a, b, wer_val))\n",
    "#         print((a, b, wer_val))\n",
    "# pd.DataFrame(data_grid, columns=[\"alpha\", \"beta\", \"wer\"]).sort_values(by=\"wer\").head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81f73ac2",
   "metadata": {},
   "outputs": [],
   "source": [
    "data_nemo = []\n",
    "for beam_width in beam_widths:\n",
    "    nemo_decoder = BeamSearchDecoderWithLM(\n",
    "        vocab=nemo_tokens,\n",
    "        beam_width=beam_width,\n",
    "        alpha=1.0,\n",
    "        beta=0,\n",
    "        lm_path=kenlm_file,\n",
    "        num_cpus=1,\n",
    "        input_tensor=False,\n",
    "    )\n",
    "    \n",
    "    pred_list = [nemo_decoder.forward(log_probs=logits, log_probs_length=None)[0][0][1] for logits in logits_nemo[:num_samples]]\n",
    "    wer_val = word_error_rate(transcription[:num_samples], pred_list)\n",
    "    \n",
    "    t0 = time.time()\n",
    "    _ = [nemo_decoder.forward(log_probs=logits, log_probs_length=None) for logits in logits_nemo[:num_samples]]\n",
    "    dur = round((time.time() - t0) / num_samples * 1000, 1)\n",
    "    data_nemo.append((wer_val * 100, dur, beam_width))\n",
    "    \n",
    "df_nemo = create_df(data_nemo)\n",
    "df_nemo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5546878-2bb1-4039-aacb-c97f4772573e",
   "metadata": {},
   "source": [
    "## Plot Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "id": "d36c1614-570c-4314-949e-3bf5ddc71ab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_pyctc = create_df(data_pyctc)\n",
    "df_torch = create_df(data_torch)\n",
    "# df_nemo = create_df(data_nemo)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "336c7fd7",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "lineplot() takes from 0 to 1 positional arguments but 2 were given",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m/tmp/ipykernel_1363144/4074412329.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_torch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"avg_dur_ms\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_torch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"wer_val\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlineplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"torchaudio\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_pyctc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"avg_dur_ms\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mTypeError\u001b[0m: lineplot() takes from 0 to 1 positional arguments but 2 were given"
     ]
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "sns.set_theme(style=\"darkgrid\")\n",
    "\n",
    "x = df_torch[\"avg_dur_ms\"].values\n",
    "y = df_torch[\"wer_val\"].values\n",
    "sns.lineplot(x, y, label=\"torchaudio\")\n",
    "\n",
    "x = df_pyctc[\"avg_dur_ms\"].values\n",
    "y = df_pyctc[\"wer_val\"].values\n",
    "sns.lineplot(x, y, label=\"pyctcdecode\")\n",
    "\n",
    "# x = df_nemo[\"avg_dur_ms\"].values\n",
    "# y = df_nemo[\"wer_val\"].values\n",
    "# sns.lineplot(x, y, label=\"nemo\")\n",
    "\n",
    "plt.xlabel('runtime / sample (ms)')\n",
    "plt.ylabel(\"word error rate (%)\")\n",
    "plt.title(\"dev-other [w2v2 base 100h]\")\n",
    "plt.axis([0, 50, 10, 20])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "32ca77ea-8faf-46d1-b8b8-2362f77e597d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[NeMo W 2022-07-05 12:16:56 nemo_logging:349] /Users/carolinechen/opt/anaconda3/envs/audio-nightly/lib/python3.8/site-packages/seaborn/_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.\n",
      "      warnings.warn(\n",
      "    \n",
      "[NeMo W 2022-07-05 12:16:56 nemo_logging:349] /Users/carolinechen/opt/anaconda3/envs/audio-nightly/lib/python3.8/site-packages/seaborn/_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.\n",
      "      warnings.warn(\n",
      "    \n",
      "[NeMo W 2022-07-05 12:16:56 nemo_logging:349] /Users/carolinechen/opt/anaconda3/envs/audio-nightly/lib/python3.8/site-packages/seaborn/_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.\n",
      "      warnings.warn(\n",
      "    \n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "d2886384-1bd1-49bc-bdb0-962e4f91aa53",
   "metadata": {},
   "source": [
    "params:\n",
    "    pyctc default prune=-10, alpha=0.8, beta=2.0, unk_logp=-10\n",
    "    nemo alpha=1.0, beta=0.0\n",
    "    fl beam_threshold=10, lm_weight=2, word_score=0, unk=-inf, sil=0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f50eb5fc-8ab2-4360-ac4e-55dd38d03b24",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>wer_val</th>\n",
       "      <th>avg_dur_ms</th>\n",
       "      <th>beam_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37.204536</td>\n",
       "      <td>0.8</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>15.429437</td>\n",
       "      <td>2.0</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>14.231037</td>\n",
       "      <td>3.0</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>12.712551</td>\n",
       "      <td>8.0</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>12.299156</td>\n",
       "      <td>11.1</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>12.273200</td>\n",
       "      <td>13.0</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     wer_val  avg_dur_ms  beam_width\n",
       "0  37.204536         0.8           1\n",
       "1  15.429437         2.0           5\n",
       "2  14.231037         3.0          10\n",
       "3  12.712551         8.0          50\n",
       "4  12.299156        11.1         100\n",
       "5  12.273200        13.0         150"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "e7b6faad-746a-44ea-8827-4ef7ae8854b0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>wer_val</th>\n",
       "      <th>avg_dur_ms</th>\n",
       "      <th>beam_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>27.719745</td>\n",
       "      <td>7.1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>16.783549</td>\n",
       "      <td>11.5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>15.380096</td>\n",
       "      <td>15.7</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>13.311726</td>\n",
       "      <td>29.3</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>13.021434</td>\n",
       "      <td>38.6</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>12.807825</td>\n",
       "      <td>45.9</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     wer_val  avg_dur_ms  beam_width\n",
       "0  27.719745         7.1           1\n",
       "1  16.783549        11.5           5\n",
       "2  15.380096        15.7          10\n",
       "3  13.311726        29.3          50\n",
       "4  13.021434        38.6         100\n",
       "5  12.807825        45.9         150"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_pyctc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "cdb7c263-9b0c-498a-9cd7-60969653b8f7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>wer_val</th>\n",
       "      <th>avg_dur_ms</th>\n",
       "      <th>beam_width</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>431.364442</td>\n",
       "      <td>2.6</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>18.211441</td>\n",
       "      <td>4.5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>15.845445</td>\n",
       "      <td>6.3</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>13.452863</td>\n",
       "      <td>21.4</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>13.033967</td>\n",
       "      <td>37.3</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>12.903968</td>\n",
       "      <td>63.9</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      wer_val  avg_dur_ms  beam_width\n",
       "0  431.364442         2.6           1\n",
       "1   18.211441         4.5           5\n",
       "2   15.845445         6.3          10\n",
       "3   13.452863        21.4          50\n",
       "4   13.033967        37.3         100\n",
       "5   12.903968        63.9         150"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_nemo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57a51a27-ae3a-495f-9d5e-5b8d8954433d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
