{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 🗣️ Lahgtna — Egyptian-Arabic TTS on Colab\n", "\n", "Run the **v3** model on a free Colab GPU.\n", "**First: Runtime → Change runtime type → T4 GPU.**" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "!pip install -q omnivoice catt-tashkeel num2words soundfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Log in to Hugging Face (private repo — use a READ token)" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "from huggingface_hub import login\n", "login()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load model + reference voice" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "import torch\n", "from omnivoice.models.omnivoice import OmniVoice\n", "from huggingface_hub import hf_hub_download\n", "\n", "REPO = \"ehabnegm/lahgtna-omnivoice-egyptian-v3\"\n", "model = OmniVoice.from_pretrained(REPO, device_map=\"cuda\", dtype=torch.float16)\n", "ref_audio = hf_hub_download(REPO, \"reference.wav\")\n", "ref_text = \"كان العمل التطوعي واللي لما تفتح الباب بس ليه الناس\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Text front-end + long-form helper (chunk → no drift)" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "import re, numpy as np, soundfile as sf\n", "from num2words import num2words\n", "_DIGITS = str.maketrans(\"٠١٢٣٤٥٦٧٨٩\", \"0123456789\")\n", "HARAKAT = re.compile(r\"[ً-ْٰـ]\")\n", "def prep(t):\n", " t = t.translate(_DIGITS)\n", " t = re.sub(r\"\\d+\", lambda m: \" \" + num2words(int(m.group()), lang=\"ar\") + \" \", t)\n", " t = re.sub(r\"[A-Za-z]+\", \" \", t)\n", " t = HARAKAT.sub(\"\", t).replace(\"ى\", \"ي\")\n", " return re.sub(r\"\\s+\", \" \", t).strip()\n", "def chunks(t):\n", " out, cur = [], \"\"\n", " for p in re.split(r\"([،؛\\.؟!\\n]+)\", t):\n", " cur += p\n", " if re.search(r\"[،؛\\.؟!\\n]\", p):\n", " if cur.strip(): out.append(cur.strip())\n", " cur = \"\"\n", " if cur.strip(): out.append(cur.strip())\n", " return out or [t]\n", "def synth(text, num_step=16):\n", " parts = [model.generate(text=prep(c), language=\"arz\", ref_audio=ref_audio, ref_text=ref_text, num_step=num_step)[0] for c in chunks(text) if prep(c)]\n", " return np.concatenate(parts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate & play" ] }, { "cell_type": "code", "metadata": {}, "execution_count": null, "outputs": [], "source": [ "from IPython.display import Audio\n", "text = \"أهلاً بحضرتك، معاك المساعد الذكي. اتفضل قوللي محتاج إيه؟\"\n", "sf.write(\"out.wav\", synth(text), 24000)\n", "Audio(\"out.wav\")" ] } ], "metadata": { "accelerator": "GPU", "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" } }, "nbformat": 4, "nbformat_minor": 0 }