{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# setup autoload\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:21.040680Z",
     "start_time": "2024-05-16T13:58:19.777010Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:15.400142Z",
     "iopub.status.busy": "2024-09-04T00:09:15.400003Z",
     "iopub.status.idle": "2024-09-04T00:09:16.826779Z",
     "shell.execute_reply": "2024-09-04T00:09:16.826272Z",
     "shell.execute_reply.started": "2024-09-04T00:09:15.400124Z"
    }
   },
   "outputs": [],
   "source": [
    "import ast\n",
    "import os\n",
    "import shutil\n",
    "import sys\n",
    "from collections import defaultdict\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from preference_data_preparation_4min_30b_task import *\n",
    "from preference_helper import *\n",
    "from sklearn.model_selection import train_test_split\n",
    "from suno_utils.utils.s3 import download_s3_files\n",
    "from suno_utils.utils.text import read_json, read_jsonl, write_json, write_jsonl\n",
    "from tqdm import tqdm\n",
    "\n",
    "pd.set_option(\"display.max_rows\", 500)\n",
    "pd.set_option(\"display.max_columns\", 500)\n",
    "pd.set_option(\"display.width\", 1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:21.082172Z",
     "start_time": "2024-05-16T13:58:21.041926Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:16.827577Z",
     "iopub.status.busy": "2024-09-04T00:09:16.827388Z",
     "iopub.status.idle": "2024-09-04T00:09:16.851235Z",
     "shell.execute_reply": "2024-09-04T00:09:16.850789Z",
     "shell.execute_reply.started": "2024-09-04T00:09:16.827561Z"
    }
   },
   "outputs": [],
   "source": [
    "OUT_DATA_DIR = \"/app/suno/data/dpo/30b_t1_v24\"\n",
    "os.makedirs(OUT_DATA_DIR, exist_ok=True)\n",
    "shutil.copyfile(\n",
    "    \"/app/suno/data/dpo/7v_v20_full/tokenizer_60k.json\",\n",
    "    os.path.join(OUT_DATA_DIR, \"tokenizer_60k.json\"),\n",
    ")\n",
    "NPZ_DIR = \"/app/suno/data/dpo/30b_npz\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:53.962528Z",
     "start_time": "2024-05-16T13:58:21.105919Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:16.852145Z",
     "iopub.status.busy": "2024-09-04T00:09:16.851815Z",
     "iopub.status.idle": "2024-09-04T00:09:17.935061Z",
     "shell.execute_reply": "2024-09-04T00:09:17.934483Z",
     "shell.execute_reply.started": "2024-09-04T00:09:16.852129Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Preference data shape (241818, 63)\n"
     ]
    }
   ],
   "source": [
    "# Still old data in csv...\n",
    "df = pd.read_csv(\n",
    "    \"/home/tony/Data/Preference/30b_v0/interesting_clips_v4_t_1_20240808.csv\"\n",
    ")  # , engine='python')\n",
    "# df = pd.read_pickle(\n",
    "#     \"/home/tony/Data/Preference/30b_v0/interesting_clips_v4_t_1_20240808_v22_slice_with_cer.pkl\"\n",
    "# )\n",
    "print(\"Preference data shape\", df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:17.935904Z",
     "iopub.status.busy": "2024-09-04T00:09:17.935737Z",
     "iopub.status.idle": "2024-09-04T00:09:18.076419Z",
     "shell.execute_reply": "2024-09-04T00:09:18.075858Z",
     "shell.execute_reply.started": "2024-09-04T00:09:17.935887Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(241818, 63)\n",
      "(241818, 59)\n"
     ]
    }
   ],
   "source": [
    "print(df.shape)\n",
    "df = df.dropna(axis=1, how=\"all\")\n",
    "print(df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.199480Z",
     "start_time": "2024-05-16T13:58:53.963687Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:18.077252Z",
     "iopub.status.busy": "2024-09-04T00:09:18.077102Z",
     "iopub.status.idle": "2024-09-04T00:09:35.314786Z",
     "shell.execute_reply": "2024-09-04T00:09:35.314068Z",
     "shell.execute_reply.started": "2024-09-04T00:09:18.077236Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6442462\n",
      "6442462\n",
      "pre-downloaded df (241818, 59)\n",
      "downloaded df (241818, 59)\n"
     ]
    }
   ],
   "source": [
    "converted_paths = os.listdir(NPZ_DIR)\n",
    "print(len(converted_paths))\n",
    "\n",
    "converted_paths = set([f.replace(\".npz\", \"\") for f in converted_paths])\n",
    "print(len(converted_paths))\n",
    "\n",
    "print(\"pre-downloaded df\", df.shape)\n",
    "df[df[\"s3_id\"].isin(converted_paths)].shape\n",
    "df = df[df[\"s3_id\"].isin(converted_paths)].copy()\n",
    "print(\"downloaded df\", df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.467253Z",
     "start_time": "2024-05-16T13:58:56.207647Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:35.316999Z",
     "iopub.status.busy": "2024-09-04T00:09:35.316667Z",
     "iopub.status.idle": "2024-09-04T00:09:35.368920Z",
     "shell.execute_reply": "2024-09-04T00:09:35.368351Z",
     "shell.execute_reply.started": "2024-09-04T00:09:35.316978Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "is_30b\n",
       "True    241818\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"is_30b\"] = df[\"model_name\"].str.contains(\"-t\")\n",
    "df[\"is_30b\"].value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LET's do the data prep"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.592883Z",
     "start_time": "2024-05-16T13:58:56.470781Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:35.369862Z",
     "iopub.status.busy": "2024-09-04T00:09:35.369702Z",
     "iopub.status.idle": "2024-09-04T00:09:35.458772Z",
     "shell.execute_reply": "2024-09-04T00:09:35.458172Z",
     "shell.execute_reply.started": "2024-09-04T00:09:35.369845Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "preference  model_name           \n",
      "False       chirp-v3p5-engine-t-1    120909\n",
      "True        chirp-v3p5-engine-t-1    120909\n",
      "Name: count, dtype: int64\n",
      "(241818, 60)\n",
      "(241818, 60)\n"
     ]
    }
   ],
   "source": [
    "## for 13b this is easy for now\n",
    "print(df.groupby([\"preference\"])[\"model_name\"].value_counts())\n",
    "print(df.shape)\n",
    "df = df[df[\"model_name\"].isin([\"chirp-v3p5-engine-t-1\"])]\n",
    "print(df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:58:56.909539Z",
     "start_time": "2024-05-16T13:58:56.595736Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:35.459699Z",
     "iopub.status.busy": "2024-09-04T00:09:35.459538Z",
     "iopub.status.idle": "2024-09-04T00:09:35.555081Z",
     "shell.execute_reply": "2024-09-04T00:09:35.554443Z",
     "shell.execute_reply.started": "2024-09-04T00:09:35.459683Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(241818, 60)\n",
      "(241818, 60)\n",
      "preference  model_name           \n",
      "False       chirp-v3p5-engine-t-1    120909\n",
      "True        chirp-v3p5-engine-t-1    120909\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df.shape)\n",
    "df = df[\n",
    "    df[\"request_id\"].isin(\n",
    "        df[\"request_id\"].value_counts().index[df[\"request_id\"].value_counts() == 2]\n",
    "    )\n",
    "]\n",
    "print(df.shape)\n",
    "print(df.groupby([\"preference\"])[\"model_name\"].value_counts())\n",
    "assert df.shape[0] == df[\"request_id\"].nunique() * 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:35.555966Z",
     "iopub.status.busy": "2024-09-04T00:09:35.555805Z",
     "iopub.status.idle": "2024-09-04T00:09:53.669688Z",
     "shell.execute_reply": "2024-09-04T00:09:53.668944Z",
     "shell.execute_reply.started": "2024-09-04T00:09:35.555949Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "unique_requests 120909\n"
     ]
    }
   ],
   "source": [
    "# Let's use the old selection for now -- for quality assurance\n",
    "# expand the metadata columns -- this takes forever...~ 6 mins\n",
    "test_slice = df[\"metadata\"].apply(lambda x: ast.literal_eval(str(x)))\n",
    "test_slice_series = test_slice.apply(pd.Series)\n",
    "df = pd.concat([df, test_slice_series], axis=1, join=\"inner\")\n",
    "print(\"unique_requests\", df[\"request_id\"].nunique())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:53.670745Z",
     "iopub.status.busy": "2024-09-04T00:09:53.670575Z",
     "iopub.status.idle": "2024-09-04T00:09:53.885752Z",
     "shell.execute_reply": "2024-09-04T00:09:53.885046Z",
     "shell.execute_reply.started": "2024-09-04T00:09:53.670727Z"
    }
   },
   "outputs": [],
   "source": [
    "df = df.loc[:, ~df.columns.duplicated()].copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:53.886767Z",
     "iopub.status.busy": "2024-09-04T00:09:53.886596Z",
     "iopub.status.idle": "2024-09-04T00:09:53.998731Z",
     "shell.execute_reply": "2024-09-04T00:09:53.998122Z",
     "shell.execute_reply.started": "2024-09-04T00:09:53.886749Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pos_diff_preference\n",
       "1.0    94264\n",
       "2.0    26645\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.sort_values(by=[\"request_id\", \"preference\", \"diff_preference\"])\n",
    "df[\"pos_diff_preference\"] = df[\"diff_preference\"].diff()\n",
    "# df[\"cer_diff_preference\"] = df[\"cer\"].diff()\n",
    "df[df[\"preference\"]][\"pos_diff_preference\"].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:53.999723Z",
     "iopub.status.busy": "2024-09-04T00:09:53.999559Z",
     "iopub.status.idle": "2024-09-04T00:09:54.370567Z",
     "shell.execute_reply": "2024-09-04T00:09:54.369970Z",
     "shell.execute_reply.started": "2024-09-04T00:09:53.999707Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2266 duplicated prompts 1133 unique requests\n",
      "Found 481 request_ids with duplicate prompts but not highest play counts in their group\n",
      "['9579e030-b581-4b4a-bf00-3f4134a511db', 'c5354ea6-12c0-40da-999b-eca2afd25ae2', 'baa56fc0-2256-4e9e-94a7-500a7e8844e8', '37494523-3342-4a42-b03b-ff4d2cb40145', '5d9922e4-b4a9-4386-946c-c3dad77e1630', '6a4d7c36-b468-44bf-b595-4bfa9a613927', '28ede57e-8616-49c1-b132-aa6b254cf614', 'c17c3be4-b91a-4698-acde-4695195a9601', 'f23dadd3-9200-467c-8ee4-a6859ea3216f', 'c9bbbd43-0149-4174-91a6-515bbf58e1d4']\n",
      "Before dedup user gen requests 241818\n",
      "After dedup user gen requests 240856\n"
     ]
    }
   ],
   "source": [
    "# Find duplicated prompts with count > 2\n",
    "duplicate_entries = df.groupby([\"user_id\", \"prompt_text\", \"tags\"]).filter(\n",
    "    lambda x: len(x) > 2\n",
    ")\n",
    "print(\n",
    "    \"Found\",\n",
    "    len(duplicate_entries),\n",
    "    \"duplicated prompts\",\n",
    "    len(duplicate_entries[\"request_id\"].unique()),\n",
    "    \"unique requests\",\n",
    ")\n",
    "\n",
    "# Group by user_id, prompt_text, and tags to find duplicate prompt groups\n",
    "prompt_groups = duplicate_entries.groupby([\"user_id\", \"prompt_text\", \"tags\"])\n",
    "\n",
    "# For each prompt group, find the request_id with the highest total reaction_play_count\n",
    "low_play_count_request_ids = []\n",
    "for prompt_key, prompt_group in prompt_groups:\n",
    "    # Get the sum of reaction_play_count for each request_id in this group\n",
    "    request_play_counts = prompt_group.groupby(\"request_id\")[\n",
    "        \"reaction_play_count\"\n",
    "    ].sum()\n",
    "\n",
    "    # Find the max play count in this group\n",
    "    max_play_count = request_play_counts.max()\n",
    "\n",
    "    # Add request_ids that don't have the max play count to our filter list\n",
    "    lower_play_count_request_ids = request_play_counts[\n",
    "        request_play_counts < max_play_count\n",
    "    ].index.tolist()\n",
    "    low_play_count_request_ids.extend(lower_play_count_request_ids)\n",
    "\n",
    "# Display the filtered request IDs\n",
    "print(\n",
    "    f\"Found {len(low_play_count_request_ids)} request_ids with duplicate prompts but not highest play counts in their group\"\n",
    ")\n",
    "print(\n",
    "    low_play_count_request_ids[:10]\n",
    "    if len(low_play_count_request_ids) > 10\n",
    "    else low_play_count_request_ids\n",
    ")\n",
    "print(\"Before dedup user gen requests\", df.shape[0])\n",
    "df = df[~df[\"request_id\"].isin(low_play_count_request_ids)]\n",
    "print(\"After dedup user gen requests\", df.shape[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:40.799375Z",
     "start_time": "2024-05-16T13:59:36.394236Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:54.371610Z",
     "iopub.status.busy": "2024-09-04T00:09:54.371441Z",
     "iopub.status.idle": "2024-09-04T00:09:54.866826Z",
     "shell.execute_reply": "2024-09-04T00:09:54.866097Z",
     "shell.execute_reply.started": "2024-09-04T00:09:54.371593Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15399\n",
      "good_continue_at\n",
      "True     240483\n",
      "False       373\n",
      "Name: count, dtype: int64\n",
      "\n",
      " Check some basics... \n",
      " preference\n",
      "False    120428\n",
      "True     120428\n",
      "Name: count, dtype: int64 is_30b\n",
      "True    240856\n",
      "Name: count, dtype: int64 model_name\n",
      "chirp-v3p5-engine-t-1    240856\n",
      "Name: count, dtype: int64 preference  model_name           \n",
      "False       chirp-v3p5-engine-t-1    120428\n",
      "True        chirp-v3p5-engine-t-1    120428\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "df[\"id\"] = df[\"str_id\"]\n",
    "# get the original duration of the clips, if they are concacted\n",
    "df[\"original_duration_s\"] = df[\"total_start_s\"] + df[\"duration\"]\n",
    "# classify the continue at behavoirs by the duration choice\n",
    "audio_prompt_id_to_continue_at = {}\n",
    "for _, row in df[~df[\"audio_prompt_id\"].isna()].iterrows():\n",
    "    audio_prompt_id = row[\"audio_prompt_id\"]\n",
    "    if audio_prompt_id not in audio_prompt_id_to_continue_at:\n",
    "        audio_prompt_id_to_continue_at[audio_prompt_id] = row[\"continue_at\"]\n",
    "    else:\n",
    "        # pick the max\n",
    "        audio_prompt_id = max(\n",
    "            audio_prompt_id_to_continue_at[audio_prompt_id], row[\"continue_at\"]\n",
    "        )\n",
    "print(len(audio_prompt_id_to_continue_at))\n",
    "df[\"has_continue_and_start_continue_at\"] = df[\"id\"].apply(\n",
    "    lambda x: audio_prompt_id_to_continue_at.get(x)\n",
    ")\n",
    "# we want continue at to be at most of the clip...\n",
    "df[\"good_continue_at\"] = (\n",
    "    (df[\"has_continue_and_start_continue_at\"] / df[\"duration\"]) > 0.9\n",
    ") | df[\"has_continue_and_start_continue_at\"].isna()\n",
    "print(df[\"good_continue_at\"].value_counts())\n",
    "\n",
    "\n",
    "print(\n",
    "    \"\\n Check some basics... \\n\",\n",
    "    df[\"preference\"].value_counts(),\n",
    "    df[\"is_30b\"].value_counts(),\n",
    "    df[\"model_name\"].value_counts(),\n",
    "    df.groupby([\"preference\"])[\"model_name\"].value_counts(),\n",
    ")\n",
    "\n",
    "df = df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "df[\"duration_rel_diff\"] = df[\"duration\"].diff()\n",
    "df[\"play_rel_diff\"] = df[\"reaction_play_count\"].diff()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.035167Z",
     "start_time": "2024-05-16T13:59:40.801098Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:10:57.387998Z",
     "iopub.status.busy": "2024-09-04T00:10:57.387393Z",
     "iopub.status.idle": "2024-09-04T00:10:57.508220Z",
     "shell.execute_reply": "2024-09-04T00:10:57.507527Z",
     "shell.execute_reply.started": "2024-09-04T00:10:57.387975Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "negative 119137 positive 65805\n",
      "total pair requests 120428  --> selected pair requests 65013 frac 0.540\n"
     ]
    }
   ],
   "source": [
    "normal_pos_play_count = 3\n",
    "# this is lower, cause a concat is probably already ensuring that it is good\n",
    "concat_pos_play_count = 1\n",
    "# this is a filter on the concated clip\n",
    "concat_total_play_count = 3\n",
    "\n",
    "neg_filter_selection_mask = (\n",
    "    (~df[\"preference\"])  # get basics aligned\n",
    "    & (df[\"reaction_play_count\"] >= 1)  # has to be played once\n",
    "    # & (df[\"play_count\"] <= 3)  # if it is actually bad, shouldn't be listened often\n",
    "    & (df[\"duration\"] >= 10)  # can't be too short, otherwise it is obvious\n",
    "    & (df[\"duration\"] <= 240)  # can't be badly long\n",
    "    & (df[\"has_continue_and_start_continue_at\"].isna())  # won't have any continues\n",
    "    & (df[\"upvote_count\"] == 0)  # won't have any likes\n",
    "    # & ((df[\"norm_play_frac\"] <= 2.1))\n",
    "    # & (df[\"dislike_count\"] >= 1) # this is kinda strict\n",
    "    #     & (\n",
    "    #         (df_slice[\"is_in_playlist\"] == False)\n",
    "    #         & (df_slice[\"concat_in_playlist\"] == False)\n",
    "    #     )  # can't be part of a playlist -- otherwise there are some like signal in it?\n",
    ")\n",
    "pos_filter_selectin_mask = (\n",
    "    (df[\"preference\"])  # get basics aligned\n",
    "    & (\n",
    "        df[\"good_continue_at\"]\n",
    "    )  # if continue, needs to continue off a certain percentage\n",
    "    & (df[\"reaction_play_count\"] >= 1)\n",
    "    & (df[\"play_rel_diff\"] >= 0)  # this is more like quality assurance\n",
    "    & (df[\"duration\"] >= 10)  # can't be too short, otherwise it is obvious\n",
    "    & (df[\"duration\"] <= 240)  # can't be badly long\n",
    "    & (df[\"dislike_count\"] == 0)  # can't have dislikes\n",
    "    & (df[\"flag_count\"] == 0)  # can't have issues\n",
    "    & (\n",
    "        (\n",
    "            (df[\"part_of_concat\"])\n",
    "            & (df[\"reaction_play_count\"] >= concat_pos_play_count)\n",
    "            & (df[\"concat_play_counts\"] >= concat_total_play_count)\n",
    "        )\n",
    "        | (\n",
    "            (~df[\"part_of_concat\"])\n",
    "            & (df[\"reaction_play_count\"] >= normal_pos_play_count)\n",
    "        )\n",
    "    )\n",
    "    # & (df[\"norm_play_frac\"] >= 1.9)\n",
    "    & (df[\"user_n_clips\"] >= 6)  # user needs to have genereated at least 20\n",
    "    # & (df[\"duration_rel_diff\"] < 10) # positive isn't just longer\n",
    "    & ((df[\"upvote_count\"] >= 1) | (df[\"reaction_play_count\"] >= 5))\n",
    "    # & ((df[\"upvote_count\"] >= 1) | (df[\"norm_play_frac\"] >= 1.9))\n",
    ")\n",
    "print(\n",
    "    \"negative\",\n",
    "    sum(neg_filter_selection_mask),\n",
    "    \"positive\",\n",
    "    sum(pos_filter_selectin_mask),\n",
    ")\n",
    "\n",
    "neg_filter_requests = df[neg_filter_selection_mask][\"request_id\"].unique()\n",
    "pos_filter_requests = df[pos_filter_selectin_mask][\"request_id\"].unique()\n",
    "# looking for very strong signal here:\n",
    "# listen to the positive/negative more than once\n",
    "# disliked one of the clips\n",
    "unique_requests = set(pos_filter_requests).intersection(neg_filter_requests)\n",
    "print(\n",
    "    \"total pair requests\",\n",
    "    df[\"request_id\"].nunique(),\n",
    "    \" --> selected pair requests\",\n",
    "    len(unique_requests),\n",
    "    f\"frac {len(unique_requests) / df['request_id'].nunique():.3f}\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.250737Z",
     "start_time": "2024-05-16T13:59:41.036434Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:11:01.847564Z",
     "iopub.status.busy": "2024-09-04T00:11:01.846944Z",
     "iopub.status.idle": "2024-09-04T00:11:02.004556Z",
     "shell.execute_reply": "2024-09-04T00:11:02.003853Z",
     "shell.execute_reply.started": "2024-09-04T00:11:01.847541Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "requests 65013 clips 130026 total khrs 6.930; N gpus for 1500 iters 8.127; 4 gpus for x iters 2031.656; n unique users 51720 n pro users 18163\n"
     ]
    }
   ],
   "source": [
    "df_slice = df[df[\"request_id\"].isin(set(unique_requests))].copy()\n",
    "print(\n",
    "    \"requests\",\n",
    "    df_slice[\"request_id\"].nunique(),\n",
    "    \"clips\",\n",
    "    df_slice.shape[0],\n",
    "    f\"total khrs {sum(df_slice['duration'] / 3600 / 1000):.3f};\",\n",
    "    f\"N gpus for 1500 iters {df_slice.shape[0] / 8 / 2 / 1000:.3f};\",\n",
    "    f\"4 gpus for x iters {df_slice.shape[0] / 8 / 2 / 4:.3f};\",\n",
    "    f\"n unique users {df_slice['user_id'].nunique()}\",\n",
    "    f\"n pro users {df_slice[df_slice['is_pro_user']]['user_id'].nunique()}\",\n",
    ")\n",
    "# 76171 152342 total khrs 2.880 n gpus for 1250 iters 3.809\n",
    "# before cer: requests 41541 clips 83082 total khrs 4.318; N gpus for 1500 iters 5.193; 4 gpus for x iters 1298.156; n unique users 31037 n pro users 15384\n",
    "# after cer: requests 30342 clips 60684 total khrs 3.145; N gpus for 1500 iters 3.793; 4 gpus for x iters 948.188; n unique users 23962 n pro users 12210"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:55.125570Z",
     "iopub.status.busy": "2024-09-04T00:09:55.125397Z",
     "iopub.status.idle": "2024-09-04T00:09:55.128042Z",
     "shell.execute_reply": "2024-09-04T00:09:55.127522Z",
     "shell.execute_reply.started": "2024-09-04T00:09:55.125551Z"
    }
   },
   "outputs": [],
   "source": [
    "# requests 17681 clips 35362 total khrs 1.815; N gpus for 1500 iters 1.473; 4 gpus for x iters 552.531; n unique users 15179 n pro users 5983"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.277006Z",
     "start_time": "2024-05-16T13:59:41.252105Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:55.128828Z",
     "iopub.status.busy": "2024-09-04T00:09:55.128685Z",
     "iopub.status.idle": "2024-09-04T00:09:55.185593Z",
     "shell.execute_reply": "2024-09-04T00:09:55.185008Z",
     "shell.execute_reply.started": "2024-09-04T00:09:55.128813Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "positive in playlist (8406, 94)\n"
     ]
    }
   ],
   "source": [
    "test_mask = (df_slice[\"preference\"]) & (\n",
    "    (df_slice[\"is_in_playlist\"]) | (df_slice[\"concat_in_playlist\"])\n",
    ")\n",
    "print(\"positive in playlist\", df_slice[test_mask].shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:55.186438Z",
     "iopub.status.busy": "2024-09-04T00:09:55.186289Z",
     "iopub.status.idle": "2024-09-04T00:09:55.527707Z",
     "shell.execute_reply": "2024-09-04T00:09:55.527104Z",
     "shell.execute_reply.started": "2024-09-04T00:09:55.186423Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_slice[df_slice[\"preference\"]][\"duration\"].hist(\n",
    "    bins=np.linspace(0, 240, 100), label=\"postiive\", alpha=0.5\n",
    ")\n",
    "df_slice[~df_slice[\"preference\"]][\"duration\"].hist(\n",
    "    bins=np.linspace(0, 240, 100), label=\"negative\", alpha=0.5\n",
    ")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.323409Z",
     "start_time": "2024-05-16T13:59:41.278278Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:55.528687Z",
     "iopub.status.busy": "2024-09-04T00:09:55.528524Z",
     "iopub.status.idle": "2024-09-04T00:09:55.531077Z",
     "shell.execute_reply": "2024-09-04T00:09:55.530577Z",
     "shell.execute_reply.started": "2024-09-04T00:09:55.528671Z"
    }
   },
   "outputs": [],
   "source": [
    "# interesting_clips_must_be_positive_mask = (\n",
    "#     (df_slice[\"upvoted\"] == True)\n",
    "#     | (df_slice[\"has_action\"] == True)\n",
    "#     | (df_slice[\"part_of_concat\"] == True)\n",
    "# )\n",
    "# interesting_clips_must_be_not_negative_mask = (df_slice[\"downvoted\"] == False) # & (df_slice[\"dislike_count\"] < 1)\n",
    "# interesting_clips_mask = interesting_clips_must_be_positive_mask & interesting_clips_must_be_not_negative_mask\n",
    "# assert interesting_clips_mask.eq(df_slice[\"preference\"]).all()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.392244Z",
     "start_time": "2024-05-16T13:59:41.324472Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:09:55.531996Z",
     "iopub.status.busy": "2024-09-04T00:09:55.531856Z",
     "iopub.status.idle": "2024-09-04T00:09:55.570433Z",
     "shell.execute_reply": "2024-09-04T00:09:55.569971Z",
     "shell.execute_reply.started": "2024-09-04T00:09:55.531982Z"
    }
   },
   "outputs": [],
   "source": [
    "# save positive ids\n",
    "# positive_preference_ids = df_slice[df_slice[\"preference\"] == False][\"s3_id\"].to_json(orient='values')\n",
    "# with open('/home/tony/Data/Preference/7b_v2/7v_v20_full_recut_id_negative.json', 'w') as file:\n",
    "#     file.write(positive_preference_ids)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T14:00:20.866354Z",
     "start_time": "2024-05-16T14:00:12.443344Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:26.764140Z",
     "iopub.status.busy": "2024-09-04T00:13:26.763536Z",
     "iopub.status.idle": "2024-09-04T00:13:26.766758Z",
     "shell.execute_reply": "2024-09-04T00:13:26.766208Z",
     "shell.execute_reply.started": "2024-09-04T00:13:26.764118Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'BREAK' 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[22], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;66;03m# df_slice[\"npz_path\"] = df_slice[\"s3_id\"].map(lambda x: f\"{NPZ_DIR}/{x}.npz\")\u001b[39;00m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;66;03m# df_slice.to_pickle(\"/home/tony/Data/Preference/30b_v0/interesting_clips_v4_t_1_20240808_v23_slice.pkl\")\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mBREAK\u001b[49m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'BREAK' is not defined"
     ]
    }
   ],
   "source": [
    "# df_slice[\"npz_path\"] = df_slice[\"s3_id\"].map(lambda x: f\"{NPZ_DIR}/{x}.npz\")\n",
    "# df_slice.to_pickle(\"/home/tony/Data/Preference/30b_v0/interesting_clips_v4_t_1_20240808_v23_slice.pkl\")\n",
    "BREAK"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Need to kick out the ones has gpt prompt -- these are pairs with different text inputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.932296Z",
     "start_time": "2024-05-16T13:59:41.932287Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:26.768183Z",
     "iopub.status.busy": "2024-09-04T00:13:26.767856Z",
     "iopub.status.idle": "2024-09-04T00:13:26.864987Z",
     "shell.execute_reply": "2024-09-04T00:13:26.864417Z",
     "shell.execute_reply.started": "2024-09-04T00:13:26.768166Z"
    }
   },
   "outputs": [],
   "source": [
    "# don't have continue at\n",
    "df_slice[df_slice[\"continue_at\"].isna()][\"request_id\"].nunique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.932966Z",
     "start_time": "2024-05-16T13:59:41.932957Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:26.865903Z",
     "iopub.status.busy": "2024-09-04T00:13:26.865750Z",
     "iopub.status.idle": "2024-09-04T00:13:26.873238Z",
     "shell.execute_reply": "2024-09-04T00:13:26.872669Z",
     "shell.execute_reply.started": "2024-09-04T00:13:26.865887Z"
    }
   },
   "outputs": [],
   "source": [
    "final_filtered_requests = df_slice[\"request_id\"].unique()\n",
    "print(len(final_filtered_requests))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.933558Z",
     "start_time": "2024-05-16T13:59:41.933550Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:26.874075Z",
     "iopub.status.busy": "2024-09-04T00:13:26.873928Z",
     "iopub.status.idle": "2024-09-04T00:13:26.905018Z",
     "shell.execute_reply": "2024-09-04T00:13:26.904535Z",
     "shell.execute_reply.started": "2024-09-04T00:13:26.874061Z"
    }
   },
   "outputs": [],
   "source": [
    "# df_slice.to_csv(\"/home/tony/Data/Preference/7b_v2/7b_before_recode_20240412\", index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.934277Z",
     "start_time": "2024-05-16T13:59:41.934268Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:26.906582Z",
     "iopub.status.busy": "2024-09-04T00:13:26.906261Z",
     "iopub.status.idle": "2024-09-04T00:13:27.106720Z",
     "shell.execute_reply": "2024-09-04T00:13:27.106051Z",
     "shell.execute_reply.started": "2024-09-04T00:13:26.906567Z"
    }
   },
   "outputs": [],
   "source": [
    "train_requests, val_requests = train_test_split(\n",
    "    sorted(list(final_filtered_requests)), test_size=0.01, random_state=42\n",
    ")\n",
    "print(len(train_requests), len(val_requests))\n",
    "\n",
    "train_df = df_slice[df_slice[\"request_id\"].isin(set(train_requests))].copy()\n",
    "val_df = df_slice[df_slice[\"request_id\"].isin(set(val_requests))].copy()\n",
    "train_df = train_df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "train_df = train_df.reset_index()\n",
    "val_df = val_df.sort_values(by=[\"request_id\", \"preference\"])\n",
    "val_df = val_df.reset_index()\n",
    "\n",
    "print(train_df.shape, val_df.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Actually make"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.934954Z",
     "start_time": "2024-05-16T13:59:41.934946Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:27.107690Z",
     "iopub.status.busy": "2024-09-04T00:13:27.107525Z",
     "iopub.status.idle": "2024-09-04T00:13:27.110082Z",
     "shell.execute_reply": "2024-09-04T00:13:27.109589Z",
     "shell.execute_reply.started": "2024-09-04T00:13:27.107672Z"
    }
   },
   "outputs": [],
   "source": [
    "# val_df[[\"request_id\", \"metadata\", \"updated_at\", \"user_id\", \"preference\"]].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.935620Z",
     "start_time": "2024-05-16T13:59:41.935613Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:27.110863Z",
     "iopub.status.busy": "2024-09-04T00:13:27.110723Z",
     "iopub.status.idle": "2024-09-04T00:13:29.024654Z",
     "shell.execute_reply": "2024-09-04T00:13:29.023924Z",
     "shell.execute_reply.started": "2024-09-04T00:13:27.110849Z"
    }
   },
   "outputs": [],
   "source": [
    "total_duration = 0\n",
    "for i, row in tqdm(train_df.iterrows(), total=len(train_df)):\n",
    "    # we need to alternate between preference: neg, pos\n",
    "    # print(i, row)\n",
    "    try:\n",
    "        assert row[\"preference\"] == (i % 2 == 1)\n",
    "    except:\n",
    "        print(i, row)\n",
    "    total_duration += row[\"duration\"]\n",
    "print(\n",
    "    f\"{round(total_duration / 60 / 60):,} hours of {train_df.shape[0]} clips, {train_df.shape[0] / 8 / 2 / 1000} nodes, {train_df.shape[0] / 8 / 2 / 2} iters\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.936268Z",
     "start_time": "2024-05-16T13:59:41.936260Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:29.025704Z",
     "iopub.status.busy": "2024-09-04T00:13:29.025526Z",
     "iopub.status.idle": "2024-09-04T00:13:38.609994Z",
     "shell.execute_reply": "2024-09-04T00:13:38.609264Z",
     "shell.execute_reply.started": "2024-09-04T00:13:29.025685Z"
    }
   },
   "outputs": [],
   "source": [
    "make_dataset(val_df, OUT_DATA_DIR, is_val=True, npz_dir=NPZ_DIR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.936964Z",
     "start_time": "2024-05-16T13:59:41.936957Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:13:38.611036Z",
     "iopub.status.busy": "2024-09-04T00:13:38.610862Z",
     "iopub.status.idle": "2024-09-04T00:29:15.422621Z",
     "shell.execute_reply": "2024-09-04T00:29:15.422027Z",
     "shell.execute_reply.started": "2024-09-04T00:13:38.611018Z"
    }
   },
   "outputs": [],
   "source": [
    "make_dataset(train_df, OUT_DATA_DIR, is_val=False, npz_dir=NPZ_DIR)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-01-29T19:46:47.549860Z",
     "start_time": "2024-01-29T19:46:47.548015Z"
    }
   },
   "source": [
    "# Validation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.937879Z",
     "start_time": "2024-05-16T13:59:41.937870Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.423561Z",
     "iopub.status.busy": "2024-09-04T00:29:15.423391Z",
     "iopub.status.idle": "2024-09-04T00:29:15.444268Z",
     "shell.execute_reply": "2024-09-04T00:29:15.443786Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.423543Z"
    }
   },
   "outputs": [],
   "source": [
    "# verify\n",
    "mm = np.memmap(os.path.join(OUT_DATA_DIR, f\"data_val.bin\"), dtype=np.uint16, mode=\"r\")\n",
    "test_metas = read_jsonl(os.path.join(OUT_DATA_DIR, f\"meta_val.jsonl\"))\n",
    "test_info = read_json(os.path.join(OUT_DATA_DIR, f\"info_val.json\"))\n",
    "mm = mm.reshape(-1, 6016, 13)\n",
    "assert len(mm) == len(test_metas)\n",
    "assert mm[:100, :, 0].min() >= 0\n",
    "assert mm[:100, :, 0].max() <= 4000\n",
    "assert mm[:100, :, 1:].min() >= 0\n",
    "assert mm[:100, :, 1:].max() <= 2048"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.938629Z",
     "start_time": "2024-05-16T13:59:41.938621Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.445026Z",
     "iopub.status.busy": "2024-09-04T00:29:15.444879Z",
     "iopub.status.idle": "2024-09-04T00:29:15.468486Z",
     "shell.execute_reply": "2024-09-04T00:29:15.468075Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.445010Z"
    }
   },
   "outputs": [],
   "source": [
    "# # randomly listen to some stuff\n",
    "# from suno_utils.tasks.dac_2c_12cb import preload_models as preload_codec_models\n",
    "# from suno_utils.tasks.dac_2c_12cb import (\n",
    "#     encode as codec_encode,\n",
    "#     decode_stream_to_full_audio as codec_decode,\n",
    "#     EMBEDDING_RATE as CODEC_EMBEDDING_RATE,\n",
    "#     decode as decode\n",
    "# )\n",
    "# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n",
    "# _ = preload_codec_models(\"/app/suno/data/dpo/models/dac_2c_25x12.pt\", device=\"cuda\")\n",
    "# assert len(test_metas) == len(mm)\n",
    "# idx_list = list(range(len(test_metas)))\n",
    "# # random.shuffle(idx_list)\n",
    "# # idx_list = [idx for idx in idx_list if \"text\" in test_metas[idx]]\n",
    "# print(len(mm))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.939205Z",
     "start_time": "2024-05-16T13:59:41.939198Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.469187Z",
     "iopub.status.busy": "2024-09-04T00:29:15.469051Z",
     "iopub.status.idle": "2024-09-04T00:29:15.501891Z",
     "shell.execute_reply": "2024-09-04T00:29:15.501488Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.469173Z"
    }
   },
   "outputs": [],
   "source": [
    "# import random\n",
    "# idx = random.choice(test_info[\"perference_0\"][\"idx_list\"])\n",
    "# assert \"original_duration_s\" in test_metas[idx]\n",
    "# # positive index should be shifted by 1\n",
    "# pos_idx = idx + 1\n",
    "# print(\n",
    "#     \"tags:\",\n",
    "#     test_metas[idx].get(\"tags\") == test_metas[pos_idx].get(\"tags\"),\n",
    "#     test_metas[idx].get(\"tags\"),\n",
    "# )\n",
    "# arr = mm[idx, 1:].copy().astype(np.int16)[:, 1:]\n",
    "# pos_arr = mm[pos_idx, 1:].copy().astype(np.int16)[:, 1:]\n",
    "# pad_idx_arr = np.where(arr == COARSE_PAD_TOKEN)[0]\n",
    "# if len(pad_idx_arr) > 0:\n",
    "#     arr = arr[: pad_idx_arr[0], :]\n",
    "# pos_pad_idx_arr = np.where(pos_arr == COARSE_PAD_TOKEN)[0]\n",
    "# if len(pos_pad_idx_arr) > 0:\n",
    "#     pos_arr = pos_arr[: pos_pad_idx_arr[0], :]\n",
    "# a = decode(arr)\n",
    "# print(\"\\n negative example \\n\", test_metas[idx])\n",
    "# a.play(compress=False)\n",
    "# pos_a = decode(pos_arr)\n",
    "# print(\"\\n positive example \\n\", test_metas[pos_idx])\n",
    "# pos_a.play(compress=False)\n",
    "# print(\n",
    "#     \"text:\",\n",
    "#     test_metas[idx].get(\"text\") == test_metas[pos_idx].get(\"text\"),\n",
    "#     test_metas[idx].get(\"text\"),\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.939977Z",
     "start_time": "2024-05-16T13:59:41.939969Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.502721Z",
     "iopub.status.busy": "2024-09-04T00:29:15.502588Z",
     "iopub.status.idle": "2024-09-04T00:29:15.537867Z",
     "shell.execute_reply": "2024-09-04T00:29:15.537481Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.502708Z"
    }
   },
   "outputs": [],
   "source": [
    "# val_df[val_df[\"tags\"] == 'a vibrant blend of experimental jazz fusion, drum-and-bass and swagger fuzzed-out guitars']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.940610Z",
     "start_time": "2024-05-16T13:59:41.940603Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.539626Z",
     "iopub.status.busy": "2024-09-04T00:29:15.539472Z",
     "iopub.status.idle": "2024-09-04T00:29:15.572553Z",
     "shell.execute_reply": "2024-09-04T00:29:15.572159Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.539612Z"
    }
   },
   "outputs": [],
   "source": [
    "# from collections import Counter\n",
    "# c = Counter()\n",
    "# for _, row in df_slice.iterrows():\n",
    "#     # print(row[\"metadata\"])\n",
    "#     for k in ast.literal_eval(row[\"metadata\"]).keys():\n",
    "#         c[k] += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.941167Z",
     "start_time": "2024-05-16T13:59:41.941159Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.573241Z",
     "iopub.status.busy": "2024-09-04T00:29:15.573101Z",
     "iopub.status.idle": "2024-09-04T00:29:15.608261Z",
     "shell.execute_reply": "2024-09-04T00:29:15.607871Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.573228Z"
    }
   },
   "outputs": [],
   "source": [
    "# original_npz_path = f\"/app/suno/data/dpo/7b_npz/{test_metas[idx]['id']}.npz\"\n",
    "# original_npz_path = \"/app/suno/data/dpo/7b_npz/729c3011-f672-4ccd-8d82-1cbf2b52ff69.npz\"\n",
    "# original_arr = np.load(original_npz_path)[\"v2_raw\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.941801Z",
     "start_time": "2024-05-16T13:59:41.941793Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.608882Z",
     "iopub.status.busy": "2024-09-04T00:29:15.608756Z",
     "iopub.status.idle": "2024-09-04T00:29:15.642822Z",
     "shell.execute_reply": "2024-09-04T00:29:15.642381Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.608869Z"
    }
   },
   "outputs": [],
   "source": [
    "def validation_on_metas(input_metas):\n",
    "    total_bad = 0\n",
    "    total_good = 0\n",
    "    for idx in range(len(input_metas)):\n",
    "        if idx % 2 == 0:\n",
    "            pos_idx = idx + 1\n",
    "            if input_metas[idx].get(\"tags\") != input_metas[pos_idx].get(\"tags\"):\n",
    "                # print(test_metas[idx].get(\"text\") == test_metas[pos_idx].get(\"text\"), test_metas[idx].get(\"tags\"), test_metas[pos_idx].get(\"tags\"))\n",
    "                total_bad += 1\n",
    "            else:\n",
    "                total_good += 1\n",
    "    print(total_good, total_bad)\n",
    "    return\n",
    "\n",
    "\n",
    "validation_on_metas(test_metas)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.942520Z",
     "start_time": "2024-05-16T13:59:41.942511Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.643740Z",
     "iopub.status.busy": "2024-09-04T00:29:15.643603Z",
     "iopub.status.idle": "2024-09-04T00:29:15.684058Z",
     "shell.execute_reply": "2024-09-04T00:29:15.683615Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.643726Z"
    }
   },
   "outputs": [],
   "source": [
    "train_info = read_json(os.path.join(OUT_DATA_DIR, f\"info_tr.json\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.943072Z",
     "start_time": "2024-05-16T13:59:41.943065Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.684764Z",
     "iopub.status.busy": "2024-09-04T00:29:15.684629Z",
     "iopub.status.idle": "2024-09-04T00:29:15.717419Z",
     "shell.execute_reply": "2024-09-04T00:29:15.717011Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.684751Z"
    }
   },
   "outputs": [],
   "source": [
    "n_neg_tr = train_info[\"perference_0\"][\"idx_list\"]\n",
    "n_pos_tr = train_info[\"perference_1\"][\"idx_list\"]\n",
    "assert len(n_pos_tr) == len(n_neg_tr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.944246Z",
     "start_time": "2024-05-16T13:59:41.944237Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.718109Z",
     "iopub.status.busy": "2024-09-04T00:29:15.717975Z",
     "iopub.status.idle": "2024-09-04T00:29:15.752964Z",
     "shell.execute_reply": "2024-09-04T00:29:15.752538Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.718095Z"
    }
   },
   "outputs": [],
   "source": [
    "total_iters = len(n_neg_tr) + len(n_pos_tr)\n",
    "print(\"total samples\", total_iters, train_df.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.945249Z",
     "start_time": "2024-05-16T13:59:41.945241Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.753638Z",
     "iopub.status.busy": "2024-09-04T00:29:15.753506Z",
     "iopub.status.idle": "2024-09-04T00:29:15.787629Z",
     "shell.execute_reply": "2024-09-04T00:29:15.787202Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.753625Z"
    }
   },
   "outputs": [],
   "source": [
    "print(\"1 epoch per batch 2, total\", total_iters / 8 / 2 / 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.945972Z",
     "start_time": "2024-05-16T13:59:41.945964Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:15.788314Z",
     "iopub.status.busy": "2024-09-04T00:29:15.788178Z",
     "iopub.status.idle": "2024-09-04T00:29:16.045890Z",
     "shell.execute_reply": "2024-09-04T00:29:16.045312Z",
     "shell.execute_reply.started": "2024-09-04T00:29:15.788301Z"
    }
   },
   "outputs": [],
   "source": [
    "# !cd /home/tony/Work/tony/slurm/30b_dpo && sbatch sbatch_ipo_30b_t1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:31:53.990882Z",
     "iopub.status.busy": "2024-09-04T00:31:53.990237Z",
     "iopub.status.idle": "2024-09-04T00:31:54.004324Z",
     "shell.execute_reply": "2024-09-04T00:31:54.003856Z",
     "shell.execute_reply.started": "2024-09-04T00:31:53.990859Z"
    }
   },
   "outputs": [],
   "source": [
    "import shutil\n",
    "\n",
    "# Basic file copy\n",
    "shutil.copy(\n",
    "    \"/home/tony/Work/tony/Preference/make_dataset_auk_30b_t1.ipynb\",\n",
    "    os.path.join(OUT_DATA_DIR, \"make_dataset.ipynb\"),\n",
    ")\n",
    "print(\"Cache kept!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# some gymathtics loading prev data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-16T13:59:41.946562Z",
     "start_time": "2024-05-16T13:59:41.946555Z"
    },
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:16.046890Z",
     "iopub.status.busy": "2024-09-04T00:29:16.046728Z",
     "iopub.status.idle": "2024-09-04T00:29:16.049428Z",
     "shell.execute_reply": "2024-09-04T00:29:16.049036Z",
     "shell.execute_reply.started": "2024-09-04T00:29:16.046875Z"
    }
   },
   "outputs": [],
   "source": [
    "# prev_v3_data = \"/app/suno/data/dpo/7v_v20_full/\"\n",
    "\n",
    "# test_val_metas = read_jsonl(os.path.join(prev_v3_data, f\"meta_val.jsonl\"))\n",
    "# test_tr_metas = read_jsonl(os.path.join(prev_v3_data, f\"meta_tr.jsonl\"))\n",
    "\n",
    "# all_ids = set()\n",
    "# for meta in test_val_metas:\n",
    "#     all_ids.add(meta[\"id\"])\n",
    "# for meta in test_tr_metas:\n",
    "#     all_ids.add(meta[\"id\"])\n",
    "# print(len(all_ids), len(test_val_metas) + len(test_tr_metas))\n",
    "\n",
    "# all_ids = list(all_ids)\n",
    "# with open(\"/home/tony/Data/Preference/7b_v2/7v_v20_full_recut_id.json\", \"w\") as fp:\n",
    "#     json.dump(all_ids, fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-04T00:29:16.050129Z",
     "iopub.status.busy": "2024-09-04T00:29:16.049987Z",
     "iopub.status.idle": "2024-09-04T00:29:16.125865Z",
     "shell.execute_reply": "2024-09-04T00:29:16.125450Z",
     "shell.execute_reply.started": "2024-09-04T00:29:16.050115Z"
    }
   },
   "outputs": [],
   "source": [
    "val_df.head(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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": 4
}
