{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"6\"\n",
    "from suno_utils.gpt.generation_prompt import ALL_AUDIO_PROMPTS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import torch\n",
    "from suno_utils.audio import Audio\n",
    "from suno_utils.gpt.generation import GenerationConfig, CfgGenerationConfig\n",
    "from suno_utils.gpt.engine import Engine\n",
    "from suno_utils.gpt.generation_engine import make_request\n",
    "\n",
    "from suno_utils.diffusion.generation import (\n",
    "    preload_models as preload_diff_models,\n",
    "    generate,\n",
    "    DiffusionGenerationConfig,\n",
    ")\n",
    "from suno_utils.diffusion.generation import encode_semantic\n",
    "from suno_utils.tasks.upsample_engine import UpsampleEngine, Request, Job\n",
    "\n",
    "\n",
    "# gpt_model_fp = \"/app/suno/checkpoints/2025-02-04_21-04-31/last_ckpt_infer.pt\"  # base\n",
    "gpt_model_fp = \"/app/suno/checkpoints/2025-04-12_03-10-00/last_ckpt_infer.pt\"  # sft\n",
    "# gpt_model_fp = \"/app/suno/checkpoints/2025-04-08_19-36-46/last_ckpt_infer.pt\"  # dpo\n",
    "\n",
    "\n",
    "diff_model_fp = \"/app/suno/data/dpo/models/diff_vae_25_peaq_v7_mar24.pt\"\n",
    "\n",
    "\n",
    "# GPT\n",
    "N_BATCH = 2\n",
    "n_skip_semantic = 1\n",
    "engine = Engine(\n",
    "    gpt_model_fp,\n",
    "    \"/app/suno/models/chirp_v2/tokenizer_60k.json\",\n",
    "    max_sequences=8 * N_BATCH,\n",
    "    compile=False,\n",
    ")\n",
    "cfg = engine.model.config\n",
    "\n",
    "# Diffusion\n",
    "_ = preload_diff_models(\n",
    "    tokenizer_filepath=\"/home/georg/notebooks/gpu_nb/tmp/tokenizer_60k.json\",\n",
    "    semantic_model_filepath=\"/home/georg/notebooks/gpu_nb/tmp/mert_25.pt\",\n",
    "    semantic_clusters_filepath=\"/home/georg/notebooks/gpu_nb/tmp/mert_25_2x4k.npy\",\n",
    "    codec_filepath=\"/app/suno/data/dpo/models/25hz_vae_peaq_kl_0.005.pth\",\n",
    "    dit_model_filepath=diff_model_fp,\n",
    "    weights_precision=torch.bfloat16,\n",
    "    compile=False,\n",
    ")\n",
    "\n",
    "up_engine = UpsampleEngine(min_chunk_size=25 * 30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.utils.clip import SunoClip\n",
    "\n",
    "sc = SunoClip(\"37f34bc3-a6e9-40b9-8a51-635c268eddb4\")\n",
    "\n",
    "sc.audio().play()\n",
    "\n",
    "semantic_arr = sc.full_arr()[:, :1]\n",
    "\n",
    "print(semantic_arr.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [],
   "source": [
    "CONTEXT_TOKENS = 350\n",
    "b_left_idx = 25 * 60\n",
    "a_left_idx = b_left_idx - CONTEXT_TOKENS\n",
    "b_right_idx = int(25 * 101)\n",
    "c_right_idx = b_right_idx + CONTEXT_TOKENS\n",
    "history_arr = semantic_arr[a_left_idx:b_left_idx].copy()\n",
    "future_arr = semantic_arr[b_right_idx:c_right_idx].copy()\n",
    "tags = \"slow, incredibly sad, face melting, epic, beautifully sung intimate anthem for the heat death of the universe\"\n",
    "infill_text = \"\"\"\n",
    "Returnal\n",
    "You've never left, give that weasel some wine\n",
    "Returnal\n",
    "You've never left, you've been here the whole time\n",
    "\n",
    "[Instrumental interlude]\n",
    "\n",
    "[Verse 2]\n",
    "Another silo full\n",
    "\"\"\"\n",
    "sample_duration_s = int(round((c_right_idx - a_left_idx) / 25))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4",
   "metadata": {},
   "outputs": [],
   "source": [
    "gconf = GenerationConfig(\n",
    "    text=infill_text,\n",
    "    text_tags=tags,\n",
    "    history_arr=history_arr,\n",
    "    future_arr=future_arr,\n",
    "    cfg_coef=1.2,\n",
    "    text_start_control_tags=\"{duration:\" + str(sample_duration_s) + \"}\",\n",
    "    # min_eos_p=0.1,\n",
    "    cfg_coef_max_steps=None,\n",
    "    cfg_coef_tags_max_steps=None,\n",
    "    n_repeat_tags=1,\n",
    "    n_repeat_neg_tags=1,\n",
    "    n_skip_semantic=n_skip_semantic,\n",
    "    cfg_coef_neg_tags=0.0,\n",
    "    text_neg_tags=None,\n",
    "    temp_semantic=0.92,\n",
    "    top_k_semantic=None,\n",
    "    top_p_semantic=None,\n",
    "    min_p_semantic=0.005,\n",
    "    n_batch=1,\n",
    "    min_text_offset=0,\n",
    "    eos_pad_duration_s=0,\n",
    "    max_gen_duration_s=int(2 * 60 / n_skip_semantic),  # just incase\n",
    "    random_seed=100,\n",
    "    cfg_streams=[\n",
    "        CfgGenerationConfig(\n",
    "            stream_type=\"custom\",\n",
    "            prompts=[\"control_start\", \"tag\", \"lyrics\", \"control_end\"]\n",
    "            + ALL_AUDIO_PROMPTS,\n",
    "            null_prompts=[\"tag\", \"lyrics_no_tags\"] + ALL_AUDIO_PROMPTS,\n",
    "            weight=2.0,\n",
    "            max_steps=25 * 60,\n",
    "        ),\n",
    "    ],\n",
    "    custom_null_fields=ALL_AUDIO_PROMPTS,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5",
   "metadata": {},
   "outputs": [],
   "source": [
    "requests = [\n",
    "    make_request(f\"{i}\", gconf, engine.model.config, engine.tokenizer)\n",
    "    for i in range(N_BATCH)\n",
    "]\n",
    "\n",
    "jobs = engine.run_request(requests, tqdm_enabled=True)\n",
    "out_gpt = []\n",
    "for n, job in enumerate(jobs):\n",
    "    stream = engine.token_generator(job)\n",
    "    arr = torch.stack(list(stream))[:, 1]\n",
    "    if arr[-1] == 4000:\n",
    "        arr = arr[:-1]\n",
    "    print(f\"{round(arr.shape[-1]/25*n_skip_semantic)}s for track {n}\")\n",
    "    # do stuff incase skip\n",
    "    arr2 = (\n",
    "        torch.zeros(arr.shape[0] * n_skip_semantic, dtype=arr.dtype)\n",
    "        + cfg.semantic_pad_token\n",
    "    )\n",
    "    arr2[::n_skip_semantic] = arr\n",
    "    # add\n",
    "    out_gpt.append(arr2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.tasks.dac_vae_100hz_peaq import decode as decode_vae\n",
    "\n",
    "infill_text_with_pad = \"\"\"\n",
    "she's the cure\n",
    "Underground, search for more\n",
    "\n",
    "[Chorus]\n",
    "Returnal\n",
    "You've never left, give that weasel some wine\n",
    "Returnal\n",
    "You've never left, you've been here the whole time\n",
    "\n",
    "[Verse 2]\n",
    "Another silo full another dark dawn\n",
    "Bending the air, love is so full\n",
    "\"\"\".strip()\n",
    "\n",
    "# upsample with 10s pad on each side just incase\n",
    "# note: for simplicity let's upsample the entire clip rather than just the infill with context\n",
    "out_audio = []\n",
    "for in_sem_arr in out_gpt:\n",
    "    gen_cfg = DiffusionGenerationConfig(\n",
    "        lyrics=infill_text_with_pad,\n",
    "        tags=tags,\n",
    "        text_cfg_coef=4.0,\n",
    "        steps=32,\n",
    "        # codec_scale_factor=0.4,\n",
    "        scale_ctx_vector=False,\n",
    "        noise_ctx_level=0.0,\n",
    "        drop_semantic_tokens=False,\n",
    "        seed=0,\n",
    "    )\n",
    "\n",
    "    request = Request(\n",
    "        id=\"dummy\",\n",
    "        generation_config=gen_cfg,\n",
    "        tokens=torch.cat(\n",
    "            [\n",
    "                torch.from_numpy(history_arr[-25 * 10 :, 0].astype(np.int32)),\n",
    "                in_sem_arr,\n",
    "                torch.from_numpy(future_arr[: 25 * 10, 0].astype(np.int32)),\n",
    "            ],\n",
    "            dim=0,\n",
    "        ),\n",
    "        input_tokens_finished=True,\n",
    "    )\n",
    "\n",
    "    result = up_engine.run_request(request).vae_latents\n",
    "    decode_vae(torch.cat(result, dim=0)).play()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "suno_clean",
   "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"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
