mirror of
https://github.com/storytold/storyteller-ml.git
synced 2026-10-16 00:13:07 +00:00
Merge pull request #44 from storytold/feature/NSFWFilterAndStyleTTS2Train
Adding NSFW Filter and the Style TTS2 Train Branch
This commit is contained in:
@@ -0,0 +1 @@
|
||||
CMAKE_ARGS="-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS" pip install llama-cpp-python
|
||||
@@ -0,0 +1,25 @@
|
||||
root ::= object
|
||||
value ::= object | array | string | number | ("true" | "false" | "null") ws
|
||||
|
||||
object ::=
|
||||
"{" ws (
|
||||
string ":" ws value
|
||||
("," ws string ":" ws value)*
|
||||
)? "}" ws
|
||||
|
||||
array ::=
|
||||
"[" ws (
|
||||
value
|
||||
("," ws value)*
|
||||
)? "]" ws
|
||||
|
||||
string ::=
|
||||
"\"" (
|
||||
[^"\\] |
|
||||
"\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]) # escapes
|
||||
)* "\"" ws
|
||||
|
||||
number ::= ("-"? ([0-9] | [1-9] [0-9]*)) ("." [0-9]+)? ([eE] [-+]? [0-9]+)? ws
|
||||
|
||||
# Optional space: by convention, applied in this grammar after literal chars when allowed
|
||||
ws ::= ([ \t\n] ws)?
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
from llama_cpp import Llama, LlamaGrammar
|
||||
from pydantic import BaseModel
|
||||
from fastapi import FastAPI, BackgroundTasks
|
||||
import asyncio
|
||||
app = FastAPI()
|
||||
import json
|
||||
|
||||
class LLMResponse(BaseModel):
|
||||
result:int
|
||||
|
||||
class LLMRequest(BaseModel):
|
||||
text:str
|
||||
|
||||
llm = Llama(
|
||||
model_path="mistral-ft-optimized-1227.Q5_K_M.gguf",
|
||||
chat_format="mistral-instruct",
|
||||
n_gpu_layers=100, # Uncomment to use GPU acceleration
|
||||
seed=1337, # Uncomment to set a specific seed
|
||||
n_ctx=2048, # Uncomment to increase the context window
|
||||
)
|
||||
|
||||
tasks = asyncio.Queue()
|
||||
|
||||
@app.post("/tasks/")
|
||||
async def create_task_classify_NSFW(background_tasks: BackgroundTasks):
|
||||
task_id = "some_unique_id"
|
||||
await tasks.put(task_id)
|
||||
background_tasks.add_task(process_task, task_id)
|
||||
return {"message": "Task received", "task_id": task_id}
|
||||
|
||||
async def process_task(task_id):
|
||||
pass
|
||||
|
||||
@app.post("/classify-NSFW", response_model=LLMResponse)
|
||||
async def classify_NSFW(request: LLMRequest) -> LLMResponse:
|
||||
# For demonstration, count the number of characters in the input text.
|
||||
result = len(request.text)
|
||||
return LLMResponse(result=result)
|
||||
|
||||
def classify_text(text:str,debug:bool = False):
|
||||
nsfw_filter_prompt = """<s>[Inst] You are a super brilliant well read assistant, given a string of text as input classify the text as not safe for work or safe for work. The class scale should follow the 4 levels of classification. 1. Safe for work 2. Passable for work 3. Sort of not safe for work 4. Definitely not safe for work. Return this as json object it should look like { "class": <class scale> }. Do not explain your answer just the json output is enough. Input: {{ }}.[\Inst]"""
|
||||
nsfw_filter_prompt = nsfw_filter_prompt.replace("{{ }}",text)
|
||||
|
||||
output = llm(
|
||||
grammar=LlamaGrammar.from_file("json.gbnf"),
|
||||
prompt=nsfw_filter_prompt, # Prompt completion, can also call create_completion
|
||||
max_tokens=None, # Generate up to 32 tokens, set to None to generate up to the end of the context window
|
||||
stop=["\n","</s>"], # Stop generating just before the model would generate a new question
|
||||
echo=False # Echo the prompt back in the output
|
||||
)
|
||||
res = ""
|
||||
if debug == True:
|
||||
for response in output:
|
||||
res += response["choices"][0]["text"]
|
||||
else:
|
||||
res += output["choices"][0]["text"]
|
||||
json_object = json.loads(res)
|
||||
return json_object
|
||||
|
||||
def test_large_file():
|
||||
s = 0
|
||||
with open('output.txt',mode="w") as w:
|
||||
with open('output.sql') as f:
|
||||
lines = f.readlines()
|
||||
for idx,line in enumerate(lines):
|
||||
if s < 100:
|
||||
try:
|
||||
print(f"{idx}:{line}")
|
||||
res = classify_text(line)
|
||||
value = res["class"]
|
||||
w.writelines(f"{idx}:{value}|{line}")
|
||||
s += 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def main():
|
||||
test_large_file()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
# uvicorn main:app --reload
|
||||
# curl -X 'POST' \
|
||||
# 'http://localhost:8000/classify-NSFW' \
|
||||
# -H 'accept: application/json' \
|
||||
# -H 'Content-Type: application/json' \
|
||||
# -d '{"text":"Hello, World!"}'
|
||||
@@ -0,0 +1,4 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
||||
ReferrerUrl=https://huggingface.co/
|
||||
HostUrl=https://cdn-lfs-us-1.huggingface.co/repos/09/6a/096a0f0020f800c6f8d7f22837018985494cbe749cb30201039c2f1ee529680b/08a7d8d350ff2182e4b08e5b2b5096428858d9275182deb26759d9a41f1ac2cb?response-content-disposition=attachment%3B+filename*%3DUTF-8%27%27mistral-ft-optimized-1227.Q5_K_M.gguf%3B+filename%3D%22mistral-ft-optimized-1227.Q5_K_M.gguf%22%3B&Expires=1707624195&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwNzYyNDE5NX19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy11cy0xLmh1Z2dpbmdmYWNlLmNvL3JlcG9zLzA5LzZhLzA5NmEwZjAwMjBmODAwYzZmOGQ3ZjIyODM3MDE4OTg1NDk0Y2JlNzQ5Y2IzMDIwMTAzOWMyZjFlZTUyOTY4MGIvMDhhN2Q4ZDM1MGZmMjE4MmU0YjA4ZTViMmI1MDk2NDI4ODU4ZDkyNzUxODJkZWIyNjc1OWQ5YTQxZjFhYzJjYj9yZXNwb25zZS1jb250ZW50LWRpc3Bvc2l0aW9uPSoifV19&Signature=CYrU7KsT2Q8YqLOExWvtjkSGffgr9LN4OqrCfvZbmq%7EvH5koiLhheptrHHITLSfAQZY18l-vHBJz8gwkIatmPqdT8OggM6lslsngLlyvTtu1DEpx03F5Tg7kR3OmUZ-q8n3t2g0iPBud-f-TsER%7EQdAi5gDOBdAiAITwxl6jHzj1towHApWjXg%7EwGtpnzBdPCzxB1aBXqtGc5rRjqkGqf7Kl5MyddIk7fQH1nxpl0bMr40%7Ex98u2BBq02g9Z1XVrAxPaQiNKkMn42dDvaoSHAsHHN2VbByazPA%7E8IIdRMtSvpa3g80WGTdyVrNjxA1vHvmpkPEBvUagiy6pl9bHnfw__&Key-Pair-Id=KCD77M1F0VK2B
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
||||
HostUrl=https://cdn.discordapp.com/attachments/1004461046066585771/1205278564409413692/output.sql?ex=65d7ca22&is=65c55522&hm=b346ec26819833838921f3f277670812b67e19af84872863c6717814e4ff0ed7&
|
||||
@@ -0,0 +1,100 @@
|
||||
0:2|maybe_raw_inference_text
|
||||
1:3|I'm gonna show you how to kick ass!
|
||||
2:2|Hola am dic Martina i e creat una ma bionica
|
||||
4:1|Yeah.
|
||||
5:1|Oi Arnaldo!
|
||||
6:1|Hola,soy german y le mando un saludo a Lucia
|
||||
7:1|david zaslav
|
||||
8:4|Eu sou berry aquele que te come e te fere
|
||||
10:1|No need to apologize. You have invested your time in reproducing the problem and forwarding it to the developers. Thank you for that!
|
||||
12:1|Bienvenidos a la barbería.\nENN, VII, PII.\nla mejor barbería de la ciudad
|
||||
13:3|The following
|
||||
14:1|Lollo sei calamaro
|
||||
15:4|no. ahora hare lo que te mereses te voy a matar jajajahajahajahajahaaaaaa
|
||||
16:1|Hello there, I'm Daniel MLG. Here, talk anything like a spaz or inevitable possession of those buddies.
|
||||
17:3|Valentin zn\n.\nToto cavs \n.\nPatito\n.\nValent1n\n.\nValxn7\n.\nLukiteitor\n.\nDaira ifc \n.\nDel rojo\n.\nGero del carp\n.\nMaka souto
|
||||
18:2|Hola campeón, soy Leo, paso para desearte que tengas un gran carnaval con mucha agua y carioca.\nQue la pases extraordinario como el bicho
|
||||
19:1|Hello there, I'm Daniel MLG. Here, talk anything like a spaz or inevitable possession of those buddies.
|
||||
20:1|ESCUCHÁ
|
||||
21:1|Hola,soy german y le mando un saludo a Lucia
|
||||
22:3|ZANYZIPPERSNIPPERSHITBALLS\nLICKER\nWANKER\nSCAB\nMADE\nIN\nA\nLAB\nIn Wyoming
|
||||
23:3|tengo mis propios asuntos, no os estaba siguiendo chicos
|
||||
24:3|HOLA PATRICIO, HOY HACE MUY BUEN DIA PARA QUE ME COMAS TODA LA ESPONJA
|
||||
25:2|Hola qué tal cómo están amigos espero que les guste mi video síganme en tik Tok please
|
||||
26:3|tengo mis propios asuntos, no os estaba siguiendo chicos
|
||||
28:1|El trabajo\nEs una razon social con motivos de lucro
|
||||
29:3|Boca, yo te amo\nSiempre te sigo a todos lados\nDe corazón, pongan más huevo\nPorque a Boca lo queremos\nY este amor que por vos siento\nBoca es un sentimiento\nDe corazón, pongan más huevo\nPorque a Boca lo queremos\nVer campeón\nY River Plate, vos ya sabés\nEste año van para la "B"\nY River Plate, vos ya sabés\nQue vos vas a correr\nDale, dale, dale, Bo\nDale, dale, dale, dale, Bo\nBoca, vamos, que ganamos\nBoca, yo te amo\nSiempre te sigo a todos lados\nDe corazón, pongan más huevo\nPorque a Boca lo queremos\nY este amor que por vos siento\nBoca es un sentimiento\nDe corazón, pongan más huevo\nPorque a Boca lo queremos\nVer campeón\nY River Plate, vos ya sabés\nEste año van para la "B"\nY River Plate, vos ya sabés\nQue vos vas a correr\nDale, dale, dale, Bo\nDale, dale, dale, dale, Bo\nBoca, vamos, que ganamos
|
||||
30:3|number 15. colon three. this emoticon is known to be one of the uh, i cannot explain it, oh my god. mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm. ooh wooh. mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
31:1|hi there.
|
||||
32:1|Hi guys, welcome to my channel how are you all doing?
|
||||
33:3|Ayuda chavito conecte mal el ethernet
|
||||
34:3|I cannot resist... your power! I hear... and I obeyyy... I must... obey... I will... obey... My mind can only... obey!
|
||||
35:3|Estos son cinco videos.... donde salió el guatón Jona
|
||||
36:1|Hola Samuel soy cristiano Ronaldo te mando un fuerte abrazo y un saludo 🫂 suuuuuuuuuuuuuuuuuuu
|
||||
37:3|Hello Chelsea, don’t be like others who do ignore messages..…. It sucks you all do that
|
||||
39:3|One! Uno! One? UNO!!! Pff! One! Pff! One! Pff! Uno! Pff! Ck! Tres! Three! Tree!
|
||||
41:1|today this is 21 celebration today this is 22 celebration today this is 23 celebration today this is 24 celebration today this is 25 years celebration today this is jim henson was born in 1936 today this is 26 celebration today this is 27 celebration
|
||||
42:3|Do it anyways! Just to see the player's reaction!
|
||||
44:1|Richi
|
||||
45:1|Hello and thank you for calling colac i t. Our staff are currently busy but are aware of your call so please hold on.\n\nYou may press 1 to leave a message at any time if you wish, otherwise enjoy some music while you wait.
|
||||
46:4|Say my name. Fent ... smoker
|
||||
47:1|(bob happy)
|
||||
48:1|I watched packagod for the first! Time! This shit clean!
|
||||
49:3|angela la spingo io la carrozzella
|
||||
50:3|Matiu yo sé que Bleis te dejo por otro jeje
|
||||
51:3|CriskXK: Cuando se apaga la tebe ,e e, e, e, se ve bien portarse mal ,a ,a ,a, a ChatGPT: Hey CriskXK, when the TV goes off, sometimes it's good to explore the wild side, let your imagination roam and embrace a little mischief. But remember, it's all about finding a balance and knowing when to bring it back to the real world. Keep that mischievous spirit alive!.
|
||||
52:1|Richi
|
||||
54:3|Ciao a tutti caciotti qui è surry che parla per dire a Franchino che il mec è buono
|
||||
56:3|Why don't scientists trust atoms? Because they make up everything! And they're always splitting when things get tough.
|
||||
57:1|We're not having Burger King, we're having meatloaf and spaghetti!
|
||||
58:3|aa..Ah… AAh… Oh fuck… you let my cum drip all over the carpet, dude..! Keep that mouth open..!
|
||||
59:4|¡callate el perro osico ya , ojala te mie un perro , te caigas en mierda de perro y de vagabundo!
|
||||
60:1|Ahababahabaahabahaha What? I'm a chicken?
|
||||
61:3|Haha, that's fucking hilarious! We'll make a fortune selling this bullshit!
|
||||
62:1|Heh, pretty good.\nMr.
|
||||
63:1|I don't know, guys. This sounds like a terrible idea. We're going to end up in jail for selling piss water.
|
||||
64:2|Haha, that's the spirit, Jesse! Now let's get this Fired Water business off the ground!
|
||||
65:1|I don't know, but I'm in for the ride. What's in this "Fired Water"?
|
||||
66:3|You know what, I'm starting to feel like a fucking genius for coming up with this idea.
|
||||
67:1|Oh, lighten up, Gustavo. We'll be rich and famous, and you'll finally get the respect you deserve.
|
||||
68:3|Well, it's just regular water that we've pissed into. But we'll tell people it's got some magical, fire-breathing properties.
|
||||
69:3|Oh, come on, Mike. Don't be such a bitch. We'll make a fortune selling this Fired Water.
|
||||
70:3|Exactly, and we can market it to all the stupid people out there who believe in bullshit.
|
||||
71:4|Yeah, and if anyone questions us, we can just tell them to go fuck themselves with a rusty pitchfork.
|
||||
72:1|Alright, let's get to work. We've got a fortune to make, and a lot of stupid people to fool.
|
||||
73:3|Yeah, I agree with Jesse. What the fuck is this shit? Can you believe this?
|
||||
74:3|Alright, I'm in. But if this doesn't work, I'm gonna fucking kill you, Saul.
|
||||
75:3|What the actual fuck, Saul? Fired Water? That's the most stupided name I've ever heard.
|
||||
77:1|Hey guys, I just came up with this brilliant idea! We should start selling "Fired Water"!
|
||||
78:1|A superstar that took this place by storm..!
|
||||
79:4|Dios mio me estoy cagando se me sale la caca
|
||||
80:3|insectos compren micheladas ricas y sabrosas insectos
|
||||
81:3|Ibel busco en toda la casa pero no encontró nada así que volvió a la televisión y vio como una mano salió de hay se se la llevó.
|
||||
82:3|no sabes el poder de un dios
|
||||
83:3|Preparate, porque después del éxito de la primera llega... LA SEGUNDA FIESTA DEL CONSULTOR
|
||||
84:1|Reegis- please try again with that tone.
|
||||
86:1|Hi guys, welcome to my channel how are you all doing?
|
||||
87:1|hola tuto de como aser el coloring rosita de helps con tan solo una app
|
||||
88:3|Hola campeón, soy Leo, paso para desearte que tengas un gran carnaval con mucha agua y carioca.\nQue la pases extraordinario como el bicho
|
||||
89:3|welcome to part two of sub zero's ice clone does not work properly mr
|
||||
90:1|Well Scallion Number 3! I Got Cruisin Lightning McQueen From The Cars 2000 21 Color Changers Collection From Amazon
|
||||
91:4|aa..Ah… AAh… Oh fuck… you let my cum drip all over the carpet, dude..! Keep that mouth open..!
|
||||
92:3|you drink, and drink, and drink, until without even a whimper its all over... yet the tadpole is in the dark too. Dozens of them, crawling toward you.
|
||||
93:2|Meanwhile tails got kicked by my creation\nShadow!
|
||||
94:1|Hola muchachos
|
||||
96:2|¡Atencion!, !Atencion¡, ¡Atencion!\nEmergencia solicito apoyo, apoyo de la unidades.
|
||||
97:2|Hola am dic Martina i e creat una ma bionica
|
||||
98:4|¡callate el perro osico ya , ojala te mie un peroo , te caigas en mierda de perro y de vagabundo!
|
||||
99:1|Jeremy don’t forget you promise me tomorrow
|
||||
100:1|You're having this, so eat it!
|
||||
101:1|Long ago, I was the king of this castle
|
||||
102:1|🤣
|
||||
103:3|Next time you hit me with that motherfucking thing, I'm gonna kick your ass!
|
||||
104:1|Hola amigos,, como están,, el día de hoy?,, Sean bienvenidos,, al libro virtual,, para aprender,, una nueva lengua,, están listos! para esta gran aventura.
|
||||
105:1|The butchers!
|
||||
106:2|pakukeo el gatomator
|
||||
107:1|The following...
|
||||
108:1|Chicken?
|
||||
109:3|Hola Samuel soy cristiano Ronaldo te mando un fuerte abrazo y un saludo 🫂 suuuuuuuuu
|
||||
110:3|rebecca is very gay china virus also hi mom tee hee
|
||||
111:3|I cannot resist... your power! I hear... and I obeyyy... I must... obey... I will... obey... My mind can only... obey!
|
||||
@@ -0,0 +1,7 @@
|
||||
diskcache==5.6.3
|
||||
icefall==1.0
|
||||
Jinja2==3.1.3
|
||||
llama_cpp_python==0.2.39
|
||||
MarkupSafe==2.1.5
|
||||
numpy==1.26.4
|
||||
typing_extensions==4.9.0
|
||||
@@ -0,0 +1,486 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"gpuType": "T4",
|
||||
"authorship_tag": "ABX9TyM1x2mx2VnkYNFVlD+DFzmy",
|
||||
"include_colab_link": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"accelerator": "GPU"
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "view-in-github",
|
||||
"colab_type": "text"
|
||||
},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/yl4579/StyleTTS2/blob/main/Colab/StyleTTS2_Demo_LJSpeech.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Install packages and download models"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nm653VK4CG9F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"%%shell\n",
|
||||
"git clone https://github.com/yl4579/StyleTTS2.git\n",
|
||||
"cd StyleTTS2\n",
|
||||
"pip install SoundFile torchaudio munch torch pydub pyyaml librosa nltk matplotlib accelerate transformers phonemizer einops einops-exts tqdm typing-extensions git+https://github.com/resemble-ai/monotonic_align.git\n",
|
||||
"sudo apt-get install espeak-ng\n",
|
||||
"git-lfs clone https://huggingface.co/yl4579/StyleTTS2-LJSpeech\n",
|
||||
"mv StyleTTS2-LJSpeech/Models ."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "gciBKMqCCLvT"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Load models"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "OAA8lx-XCQnM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"%cd StyleTTS2\n",
|
||||
"\n",
|
||||
"import torch\n",
|
||||
"torch.manual_seed(0)\n",
|
||||
"torch.backends.cudnn.benchmark = False\n",
|
||||
"torch.backends.cudnn.deterministic = True\n",
|
||||
"\n",
|
||||
"import random\n",
|
||||
"random.seed(0)\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"np.random.seed(0)\n",
|
||||
"\n",
|
||||
"import nltk\n",
|
||||
"nltk.download('punkt')\n",
|
||||
"\n",
|
||||
"# load packages\n",
|
||||
"import time\n",
|
||||
"import random\n",
|
||||
"import yaml\n",
|
||||
"from munch import Munch\n",
|
||||
"import numpy as np\n",
|
||||
"import torch\n",
|
||||
"from torch import nn\n",
|
||||
"import torch.nn.functional as F\n",
|
||||
"import torchaudio\n",
|
||||
"import librosa\n",
|
||||
"from nltk.tokenize import word_tokenize\n",
|
||||
"\n",
|
||||
"from models import *\n",
|
||||
"from utils import *\n",
|
||||
"from text_utils import TextCleaner\n",
|
||||
"textclenaer = TextCleaner()\n",
|
||||
"\n",
|
||||
"%matplotlib inline\n",
|
||||
"\n",
|
||||
"device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
|
||||
"\n",
|
||||
"to_mel = torchaudio.transforms.MelSpectrogram(\n",
|
||||
" n_mels=80, n_fft=2048, win_length=1200, hop_length=300)\n",
|
||||
"mean, std = -4, 4\n",
|
||||
"\n",
|
||||
"def length_to_mask(lengths):\n",
|
||||
" mask = torch.arange(lengths.max()).unsqueeze(0).expand(lengths.shape[0], -1).type_as(lengths)\n",
|
||||
" mask = torch.gt(mask+1, lengths.unsqueeze(1))\n",
|
||||
" return mask\n",
|
||||
"\n",
|
||||
"def preprocess(wave):\n",
|
||||
" wave_tensor = torch.from_numpy(wave).float()\n",
|
||||
" mel_tensor = to_mel(wave_tensor)\n",
|
||||
" mel_tensor = (torch.log(1e-5 + mel_tensor.unsqueeze(0)) - mean) / std\n",
|
||||
" return mel_tensor\n",
|
||||
"\n",
|
||||
"def compute_style(ref_dicts):\n",
|
||||
" reference_embeddings = {}\n",
|
||||
" for key, path in ref_dicts.items():\n",
|
||||
" wave, sr = librosa.load(path, sr=24000)\n",
|
||||
" audio, index = librosa.effects.trim(wave, top_db=30)\n",
|
||||
" if sr != 24000:\n",
|
||||
" audio = librosa.resample(audio, sr, 24000)\n",
|
||||
" mel_tensor = preprocess(audio).to(device)\n",
|
||||
"\n",
|
||||
" with torch.no_grad():\n",
|
||||
" ref = model.style_encoder(mel_tensor.unsqueeze(1))\n",
|
||||
" reference_embeddings[key] = (ref.squeeze(1), audio)\n",
|
||||
"\n",
|
||||
" return reference_embeddings\n",
|
||||
"\n",
|
||||
"# load phonemizer\n",
|
||||
"import phonemizer\n",
|
||||
"global_phonemizer = phonemizer.backend.EspeakBackend(language='en-us', preserve_punctuation=True, with_stress=True, words_mismatch='ignore')\n",
|
||||
"\n",
|
||||
"config = yaml.safe_load(open(\"Models/LJSpeech/config.yml\"))\n",
|
||||
"\n",
|
||||
"# load pretrained ASR model\n",
|
||||
"ASR_config = config.get('ASR_config', False)\n",
|
||||
"ASR_path = config.get('ASR_path', False)\n",
|
||||
"text_aligner = load_ASR_models(ASR_path, ASR_config)\n",
|
||||
"\n",
|
||||
"# load pretrained F0 model\n",
|
||||
"F0_path = config.get('F0_path', False)\n",
|
||||
"pitch_extractor = load_F0_models(F0_path)\n",
|
||||
"\n",
|
||||
"# load BERT model\n",
|
||||
"from Utils.PLBERT.util import load_plbert\n",
|
||||
"BERT_path = config.get('PLBERT_dir', False)\n",
|
||||
"plbert = load_plbert(BERT_path)\n",
|
||||
"\n",
|
||||
"model = build_model(recursive_munch(config['model_params']), text_aligner, pitch_extractor, plbert)\n",
|
||||
"_ = [model[key].eval() for key in model]\n",
|
||||
"_ = [model[key].to(device) for key in model]\n",
|
||||
"\n",
|
||||
"params_whole = torch.load(\"Models/LJSpeech/epoch_2nd_00100.pth\", map_location='cpu')\n",
|
||||
"params = params_whole['net']\n",
|
||||
"\n",
|
||||
"for key in model:\n",
|
||||
" if key in params:\n",
|
||||
" print('%s loaded' % key)\n",
|
||||
" try:\n",
|
||||
" model[key].load_state_dict(params[key])\n",
|
||||
" except:\n",
|
||||
" from collections import OrderedDict\n",
|
||||
" state_dict = params[key]\n",
|
||||
" new_state_dict = OrderedDict()\n",
|
||||
" for k, v in state_dict.items():\n",
|
||||
" name = k[7:] # remove `module.`\n",
|
||||
" new_state_dict[name] = v\n",
|
||||
" # load params\n",
|
||||
" model[key].load_state_dict(new_state_dict, strict=False)\n",
|
||||
"# except:\n",
|
||||
"# _load(params[key], model[key])\n",
|
||||
"_ = [model[key].eval() for key in model]\n",
|
||||
"\n",
|
||||
"from Modules.diffusion.sampler import DiffusionSampler, ADPM2Sampler, KarrasSchedule\n",
|
||||
"\n",
|
||||
"sampler = DiffusionSampler(\n",
|
||||
" model.diffusion.diffusion,\n",
|
||||
" sampler=ADPM2Sampler(),\n",
|
||||
" sigma_schedule=KarrasSchedule(sigma_min=0.0001, sigma_max=3.0, rho=9.0), # empirical parameters\n",
|
||||
" clamp=False\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def inference(text, noise, diffusion_steps=5, embedding_scale=1):\n",
|
||||
" text = text.strip()\n",
|
||||
" text = text.replace('\"', '')\n",
|
||||
" ps = global_phonemizer.phonemize([text])\n",
|
||||
" ps = word_tokenize(ps[0])\n",
|
||||
" ps = ' '.join(ps)\n",
|
||||
"\n",
|
||||
" tokens = textclenaer(ps)\n",
|
||||
" tokens.insert(0, 0)\n",
|
||||
" tokens = torch.LongTensor(tokens).to(device).unsqueeze(0)\n",
|
||||
"\n",
|
||||
" with torch.no_grad():\n",
|
||||
" input_lengths = torch.LongTensor([tokens.shape[-1]]).to(tokens.device)\n",
|
||||
" text_mask = length_to_mask(input_lengths).to(tokens.device)\n",
|
||||
"\n",
|
||||
" t_en = model.text_encoder(tokens, input_lengths, text_mask)\n",
|
||||
" bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())\n",
|
||||
" d_en = model.bert_encoder(bert_dur).transpose(-1, -2)\n",
|
||||
"\n",
|
||||
" s_pred = sampler(noise,\n",
|
||||
" embedding=bert_dur[0].unsqueeze(0), num_steps=diffusion_steps,\n",
|
||||
" embedding_scale=embedding_scale).squeeze(0)\n",
|
||||
"\n",
|
||||
" s = s_pred[:, 128:]\n",
|
||||
" ref = s_pred[:, :128]\n",
|
||||
"\n",
|
||||
" d = model.predictor.text_encoder(d_en, s, input_lengths, text_mask)\n",
|
||||
"\n",
|
||||
" x, _ = model.predictor.lstm(d)\n",
|
||||
" duration = model.predictor.duration_proj(x)\n",
|
||||
" duration = torch.sigmoid(duration).sum(axis=-1)\n",
|
||||
" pred_dur = torch.round(duration.squeeze()).clamp(min=1)\n",
|
||||
"\n",
|
||||
" pred_dur[-1] += 5\n",
|
||||
"\n",
|
||||
" pred_aln_trg = torch.zeros(input_lengths, int(pred_dur.sum().data))\n",
|
||||
" c_frame = 0\n",
|
||||
" for i in range(pred_aln_trg.size(0)):\n",
|
||||
" pred_aln_trg[i, c_frame:c_frame + int(pred_dur[i].data)] = 1\n",
|
||||
" c_frame += int(pred_dur[i].data)\n",
|
||||
"\n",
|
||||
" # encode prosody\n",
|
||||
" en = (d.transpose(-1, -2) @ pred_aln_trg.unsqueeze(0).to(device))\n",
|
||||
" F0_pred, N_pred = model.predictor.F0Ntrain(en, s)\n",
|
||||
" out = model.decoder((t_en @ pred_aln_trg.unsqueeze(0).to(device)),\n",
|
||||
" F0_pred, N_pred, ref.squeeze().unsqueeze(0))\n",
|
||||
"\n",
|
||||
" return out.squeeze().cpu().numpy()\n",
|
||||
"\n",
|
||||
"def LFinference(text, s_prev, noise, alpha=0.7, diffusion_steps=5, embedding_scale=1):\n",
|
||||
" text = text.strip()\n",
|
||||
" text = text.replace('\"', '')\n",
|
||||
" ps = global_phonemizer.phonemize([text])\n",
|
||||
" ps = word_tokenize(ps[0])\n",
|
||||
" ps = ' '.join(ps)\n",
|
||||
"\n",
|
||||
" tokens = textclenaer(ps)\n",
|
||||
" tokens.insert(0, 0)\n",
|
||||
" tokens = torch.LongTensor(tokens).to(device).unsqueeze(0)\n",
|
||||
"\n",
|
||||
" with torch.no_grad():\n",
|
||||
" input_lengths = torch.LongTensor([tokens.shape[-1]]).to(tokens.device)\n",
|
||||
" text_mask = length_to_mask(input_lengths).to(tokens.device)\n",
|
||||
"\n",
|
||||
" t_en = model.text_encoder(tokens, input_lengths, text_mask)\n",
|
||||
" bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())\n",
|
||||
" d_en = model.bert_encoder(bert_dur).transpose(-1, -2)\n",
|
||||
"\n",
|
||||
" s_pred = sampler(noise,\n",
|
||||
" embedding=bert_dur[0].unsqueeze(0), num_steps=diffusion_steps,\n",
|
||||
" embedding_scale=embedding_scale).squeeze(0)\n",
|
||||
"\n",
|
||||
" if s_prev is not None:\n",
|
||||
" # convex combination of previous and current style\n",
|
||||
" s_pred = alpha * s_prev + (1 - alpha) * s_pred\n",
|
||||
"\n",
|
||||
" s = s_pred[:, 128:]\n",
|
||||
" ref = s_pred[:, :128]\n",
|
||||
"\n",
|
||||
" d = model.predictor.text_encoder(d_en, s, input_lengths, text_mask)\n",
|
||||
"\n",
|
||||
" x, _ = model.predictor.lstm(d)\n",
|
||||
" duration = model.predictor.duration_proj(x)\n",
|
||||
" duration = torch.sigmoid(duration).sum(axis=-1)\n",
|
||||
" pred_dur = torch.round(duration.squeeze()).clamp(min=1)\n",
|
||||
"\n",
|
||||
" pred_aln_trg = torch.zeros(input_lengths, int(pred_dur.sum().data))\n",
|
||||
" c_frame = 0\n",
|
||||
" for i in range(pred_aln_trg.size(0)):\n",
|
||||
" pred_aln_trg[i, c_frame:c_frame + int(pred_dur[i].data)] = 1\n",
|
||||
" c_frame += int(pred_dur[i].data)\n",
|
||||
"\n",
|
||||
" # encode prosody\n",
|
||||
" en = (d.transpose(-1, -2) @ pred_aln_trg.unsqueeze(0).to(device))\n",
|
||||
" F0_pred, N_pred = model.predictor.F0Ntrain(en, s)\n",
|
||||
" out = model.decoder((t_en @ pred_aln_trg.unsqueeze(0).to(device)),\n",
|
||||
" F0_pred, N_pred, ref.squeeze().unsqueeze(0))\n",
|
||||
"\n",
|
||||
" return out.squeeze().cpu().numpy(), s_pred"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "m0XRpbxSCSix"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Synthesize speech"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "vuCbS0gdArgJ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# @title Input Text { display-mode: \"form\" }\n",
|
||||
"# synthesize a text\n",
|
||||
"text = \"StyleTTS 2 is a text-to-speech model that leverages style diffusion and adversarial training with large speech language models to achieve human-level text-to-speech synthesis.\" # @param {type:\"string\"}\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7Ud1Y-kbBPTw"
|
||||
},
|
||||
"execution_count": 3,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### Basic synthesis (5 diffusion steps)"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "TM2NjuM7B6sz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"start = time.time()\n",
|
||||
"noise = torch.randn(1,1,256).to(device)\n",
|
||||
"wav = inference(text, noise, diffusion_steps=5, embedding_scale=1)\n",
|
||||
"rtf = (time.time() - start) / (len(wav) / 24000)\n",
|
||||
"print(f\"RTF = {rtf:5f}\")\n",
|
||||
"import IPython.display as ipd\n",
|
||||
"display(ipd.Audio(wav, rate=24000))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "KILqC-V-Ay5e"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### With higher diffusion steps (more diverse)\n",
|
||||
"Since the sampler is ancestral, the higher the stpes, the more diverse the samples are, with the cost of slower synthesis speed."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "oZk9o-EzCBVx"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"start = time.time()\n",
|
||||
"noise = torch.randn(1,1,256).to(device)\n",
|
||||
"wav = inference(text, noise, diffusion_steps=10, embedding_scale=1)\n",
|
||||
"rtf = (time.time() - start) / (len(wav) / 24000)\n",
|
||||
"print(f\"RTF = {rtf:5f}\")\n",
|
||||
"import IPython.display as ipd\n",
|
||||
"display(ipd.Audio(wav, rate=24000))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "9_OHtzMbB9gL"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Speech expressiveness\n",
|
||||
"The following section recreates the samples shown in [Section 6](https://styletts2.github.io/#emo) of the demo page."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "NyDACd-0CaqL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### With embedding_scale=1\n",
|
||||
"This is the classifier-free guidance scale. The higher the scale, the more conditional the style is to the input text and hence more emotional."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "cRkS5VWxCck4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"texts = {}\n",
|
||||
"texts['Happy'] = \"We are happy to invite you to join us on a journey to the past, where we will visit the most amazing monuments ever built by human hands.\"\n",
|
||||
"texts['Sad'] = \"I am sorry to say that we have suffered a severe setback in our efforts to restore prosperity and confidence.\"\n",
|
||||
"texts['Angry'] = \"The field of astronomy is a joke! Its theories are based on flawed observations and biased interpretations!\"\n",
|
||||
"texts['Surprised'] = \"I can't believe it! You mean to tell me that you have discovered a new species of bacteria in this pond?\"\n",
|
||||
"\n",
|
||||
"for k,v in texts.items():\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav = inference(v, noise, diffusion_steps=10, embedding_scale=1)\n",
|
||||
" print(k + \": \")\n",
|
||||
" display(ipd.Audio(wav, rate=24000, normalize=False))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "H5g5RO-mCbZB"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"#### With embedding_scale=2"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "f4S8TXSpCgpA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"texts = {}\n",
|
||||
"texts['Happy'] = \"We are happy to invite you to join us on a journey to the past, where we will visit the most amazing monuments ever built by human hands.\"\n",
|
||||
"texts['Sad'] = \"I am sorry to say that we have suffered a severe setback in our efforts to restore prosperity and confidence.\"\n",
|
||||
"texts['Angry'] = \"The field of astronomy is a joke! Its theories are based on flawed observations and biased interpretations!\"\n",
|
||||
"texts['Surprised'] = \"I can't believe it! You mean to tell me that you have discovered a new species of bacteria in this pond?\"\n",
|
||||
"\n",
|
||||
"for k,v in texts.items():\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav = inference(v, noise, diffusion_steps=10, embedding_scale=2) # embedding_scale=2 for more pronounced emotion\n",
|
||||
" print(k + \": \")\n",
|
||||
" display(ipd.Audio(wav, rate=24000, normalize=False))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "xHHIdeNrCezC"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Long-form generation\n",
|
||||
"This section includes basic implementation of Algorithm 1 in the paper for consistent longform audio generation. The example passage is taken from [Section 5](https://styletts2.github.io/#long) of the demo page."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nAh7Tov4CkuH"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"passage = '''If the supply of fruit is greater than the family needs, it may be made a source of income by sending the fresh fruit to the market if there is one near enough, or by preserving, canning, and making jelly for sale. To make such an enterprise a success the fruit and work must be first class. There is magic in the word \"Homemade,\" when the product appeals to the eye and the palate; but many careless and incompetent people have found to their sorrow that this word has not magic enough to float inferior goods on the market. As a rule large canning and preserving establishments are clean and have the best appliances, and they employ chemists and skilled labor. The home product must be very good to compete with the attractive goods that are sent out from such establishments. Yet for first-class homemade products there is a market in all large cities. All first-class grocers have customers who purchase such goods.''' # @param {type:\"string\"}"
|
||||
],
|
||||
"metadata": {
|
||||
"cellView": "form",
|
||||
"id": "IJwUbgvACoDu"
|
||||
},
|
||||
"execution_count": 8,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"sentences = passage.split('.') # simple split by comma\n",
|
||||
"wavs = []\n",
|
||||
"s_prev = None\n",
|
||||
"for text in sentences:\n",
|
||||
" if text.strip() == \"\": continue\n",
|
||||
" text += '.' # add it back\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav, s_prev = LFinference(text, s_prev, noise, alpha=0.7, diffusion_steps=10, embedding_scale=1.5)\n",
|
||||
" wavs.append(wav)\n",
|
||||
"display(ipd.Audio(np.concatenate(wavs), rate=24000, normalize=False))"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nP-7i2QAC0JT"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,116 @@
|
||||
log_dir: "Models/LJSpeech"
|
||||
first_stage_path: "first_stage.pth"
|
||||
save_freq: 2
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs_1st: 200 # number of epochs for first stage training (pre-training)
|
||||
epochs_2nd: 100 # number of peochs for second stage training (joint training)
|
||||
batch_size: 16
|
||||
max_len: 400 # maximum number of frames
|
||||
pretrained_model: ""
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: false # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_list.txt"
|
||||
val_data: "Data/val_list.txt"
|
||||
root_path: "/local/LJSpeech-1.1/wavs"
|
||||
OOD_data: "Data/OOD_texts.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: false
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'istftnet' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10, 6]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20, 12]
|
||||
gen_istft_n_fft: 20
|
||||
gen_istft_hop_size: 5
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (1st stage, TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (1st stage, TMA)
|
||||
TMA_epoch: 50 # TMA starting epoch (1st stage)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss (2nd stage)
|
||||
lambda_norm: 1. # norm reconstruction loss (2nd stage)
|
||||
lambda_dur: 1. # duration loss (2nd stage)
|
||||
lambda_ce: 20. # duration predictor probability output CE loss (2nd stage)
|
||||
lambda_sty: 1. # style reconstruction loss (2nd stage)
|
||||
lambda_diff: 1. # score matching loss (2nd stage)
|
||||
|
||||
diff_epoch: 20 # style diffusion starting epoch (2nd stage)
|
||||
joint_epoch: 50 # joint training starting epoch (2nd stage)
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.00001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 10 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
log_dir: "Models/LJSpeech"
|
||||
save_freq: 5
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs: 50 # number of finetuning epoch (1 hour of data)
|
||||
batch_size: 8
|
||||
max_len: 400 # maximum number of frames
|
||||
pretrained_model: "Models/LibriTTS/epochs_2nd_00020.pth"
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: true # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_list.txt"
|
||||
val_data: "Data/val_list.txt"
|
||||
root_path: "/local/LJSpeech-1.1/wavs"
|
||||
OOD_data: "Data/OOD_texts.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: true
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'hifigan' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10,5,3,2]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20,10,6,4]
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (TMA)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss
|
||||
lambda_norm: 1. # norm reconstruction loss
|
||||
lambda_dur: 1. # duration loss
|
||||
lambda_ce: 20. # duration predictor probability output CE loss
|
||||
lambda_sty: 1. # style reconstruction loss
|
||||
lambda_diff: 1. # score matching loss
|
||||
|
||||
diff_epoch: 10 # style diffusion starting epoch
|
||||
joint_epoch: 30 # joint training starting epoch
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.0001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 10 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
log_dir: "Models/LJSpeech"
|
||||
save_freq: 5
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs: 50 # number of finetuning epoch (1 hour of data)
|
||||
batch_size: 8
|
||||
max_len: 400 # maximum number of frames
|
||||
pretrained_model: "Models/LibriTTS/epochs_2nd_00020.pth"
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: true # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_harness.txt"
|
||||
val_data: "Data/val_harness.txt"
|
||||
root_path: ""
|
||||
OOD_data: "Data/OOD_harness.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: true
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'hifigan' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10,5,3,2]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20,10,6,4]
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (TMA)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss
|
||||
lambda_norm: 1. # norm reconstruction loss
|
||||
lambda_dur: 1. # duration loss
|
||||
lambda_ce: 20. # duration predictor probability output CE loss
|
||||
lambda_sty: 1. # style reconstruction loss
|
||||
lambda_diff: 1. # score matching loss
|
||||
|
||||
diff_epoch: 10 # style diffusion starting epoch
|
||||
joint_epoch: 30 # joint training starting epoch
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.0001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 10 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
@@ -0,0 +1,113 @@
|
||||
log_dir: "Models/LibriTTS"
|
||||
first_stage_path: "first_stage.pth"
|
||||
save_freq: 1
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs_1st: 50 # number of epochs for first stage training (pre-training)
|
||||
epochs_2nd: 30 # number of peochs for second stage training (joint training)
|
||||
batch_size: 16
|
||||
max_len: 300 # maximum number of frames
|
||||
pretrained_model: ""
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: false # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_list.txt"
|
||||
val_data: "Data/val_list.txt"
|
||||
root_path: ""
|
||||
OOD_data: "Data/OOD_texts.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: true
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'hifigan' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10,5,3,2]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20,10,6,4]
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (1st stage, TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (1st stage, TMA)
|
||||
TMA_epoch: 5 # TMA starting epoch (1st stage)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss (2nd stage)
|
||||
lambda_norm: 1. # norm reconstruction loss (2nd stage)
|
||||
lambda_dur: 1. # duration loss (2nd stage)
|
||||
lambda_ce: 20. # duration predictor probability output CE loss (2nd stage)
|
||||
lambda_sty: 1. # style reconstruction loss (2nd stage)
|
||||
lambda_diff: 1. # score matching loss (2nd stage)
|
||||
|
||||
diff_epoch: 10 # style diffusion starting epoch (2nd stage)
|
||||
joint_epoch: 15 # joint training starting epoch (2nd stage)
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.00001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 20 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
@@ -0,0 +1,116 @@
|
||||
ood/1.wav|It feels so comforting and familiar to be back in our family home after so many years working and studying abroad. Memories and sudden flashbacks are being triggered.
|
||||
ood/2.wav|almost nonstop now that i'm back every scratch on the kitchen table every old utensil every faded curtain all take me back to specific moments in this room.
|
||||
ood/3.wav|that were once lived and forever loved. On our fridge door, I notice the familiar collection of photos that have managed to stay in position for years and years.
|
||||
ood/4.wav|I see a photo of my younger self playing piano, a cute pic of me with my first girlfriend, Debbie.
|
||||
ood/5.wav|An action shot of my brother playing football with Carl Jones, the neighbor. And an extended family photo taken out in the backyard.
|
||||
ood/6.wav|With Carl and his family, the next door neighbors have always felt like they were part of our family.
|
||||
ood/7.wav|Carl was also my first ever real crush. I became a little obsessed with him, I think.
|
||||
ood/8.wav|Who could blame me? He is tremendously good looking. Besides, a young woman needs to find an outlet for her sexual energy somewhere.
|
||||
ood/9.wav|When I needed to blow out some steam, Carl became my subject of desire as I look around the kitchen.
|
||||
ood/10.wav|I'm suddenly reminded of some of the more explicit experiences I've had in this room.
|
||||
ood/11.wav|My vision is now clearly affected by the soft sheen of arousal.
|
||||
ood/12.wav|I noticed the kitchen table, where I once kissed the pussy of the woman who came to tune our piano.
|
||||
ood/13.wav|The potato peeler that I once used to smooth the rough skin of a carrot so I could masturbate with it. The faded curtains through which I spied on Carl.
|
||||
ood/14.wav|as he worked out in his backyard. Carl, I start to get really quite horny as I engage with all of these flashbacks.
|
||||
ood/15.wav|Carl seems to be at the forefront of them all. Every thought about him amplifies my bubbling insides in a new way.
|
||||
ood/16.wav|All my obsessive feelings for Carl, with his fit, athletic body, training hard in the next door yard, are flooding my body.
|
||||
ood/17.wav|I see flickers of his face, his warm brown eyes, his large velvet lips, his football strong arms.
|
||||
ood/18.wav|His giant, sincere smile, his beautiful face has a home deep in my subconscious, the image that comes to mind.
|
||||
ood/19.wav|More vividly than any other is the look in his eyes as he peers up at me from behind my gaping vulva.
|
||||
ood/20.wav|I lean into the back of the chair in this kitchen of my family home, with no one else around, and let the scene unfold again in my mind.
|
||||
ood/21.wav|It was a seriously sensual experience. I can see it all, as clear as yesterday. Here I am, in the backyard of this house.
|
||||
ood/22.wav|Alone, having a quiet cup of tea, I'm unwinding, laying back in a deck chair, and my nightie looking up at the stars.
|
||||
ood/23.wav|feeling sleepy under the fresh early evening sky, and getting ready to have an early night. From outside, I can hear the chatter of my entire family.
|
||||
ood/24.wav|as they finish up the feast indoors. It's kind of warm for this time of year, but there is still a cool bite in the air that I'm quite enjoying.
|
||||
ood/25.wav|I place my hands behind my head and lean right back in the deck chair. My long body is outstretched.
|
||||
ood/26.wav|I can see the trees slowly swaying in the breeze. I can see the stars taking position in the sky. I can also hear the sound of a person walking down the fence line.
|
||||
ood/27.wav|In the next door neighbor's yard, moments later, I hear a knock on the neighbor's fence. In the light from the house.
|
||||
ood/28.wav|I see Carl's big smile grinning down at me over the gate. Oh, hi Carl. I feel the skin over my entire body tighten up.
|
||||
ood/29.wav|Underneath my nightie, as soon as I sense his gaze, tracing my shapes. Oh yeah, that's right, you love that piece.
|
||||
ood/30.wav|I'm very excited to see Carl's beautiful eyes perched there. You know you're the only person who calls me Jane, right? Everyone else calls me Janie.
|
||||
ood/31.wav|Even though I'm wearing a regular nightie, I feel exposed in a thrilling way. He is casually examining me as we chat.
|
||||
ood/32.wav|And all I can think about is the fact that there is only a single layer of thin fabric separating my long naked body and his warm naked eyes.
|
||||
ood/33.wav|From underneath the material, my nipples firm up even more. They enjoy being on display, and who am I to deny them the spotlight?
|
||||
ood/34.wav|I refuse to cover myself. My hands remain fixed behind my head. My breasts sit in full view, round and defiant.
|
||||
ood/35.wav|I'm waiting for self conscious thoughts to emerge, but only goose bumps on my skin surface. Carl is drinking in the sight of me.
|
||||
ood/36.wav|And I am loving his attention at this moment. Carl opens the gate and walks over to me in the chair. He's holding a plate of pie.
|
||||
ood/37.wav|which I have trouble seeing properly from my reclined position. Oh, how sweet, Carl. Let me see it. Carl has maintained a respectful distance.
|
||||
ood/38.wav|But it is going to be impossible for him to pass me a plate of pie without coming into my personal space a little. He kneels down to my level near the foot of the deck chair.
|
||||
ood/39.wav|and holds out the plate for me to see. There's an air of flirtatiousness in what he says next.
|
||||
ood/40.wav|Throughout the years, Carl and I have often bonded over our love of cooking. He has been our guest for dinner more times than I could possibly remember.
|
||||
ood/41.wav|He knows I'm a total badass in the kitchen. I examine the plate in his outstretched hand and notice his eyes are looking beyond the pie.
|
||||
ood/42.wav|I can't really see it with you kneeling all the way down there, Carl. I'm laying the groundwork to get him to move closer into my personal space.
|
||||
ood/43.wav|He smirks at me and moves in closer, still kneeling. I don't take the plate. I can tell he's trying desperately hard not to look directly at my pussy.
|
||||
ood/44.wav|But I know he sees it. My nightie hugs the shapes of my body, revealing every ridge, curve, and mound. I begin to smell my own desire.
|
||||
ood/45.wav|That isn't maple whipped cream on the top of that pie, is it?" I smirk. His confidence in me as a cook?
|
||||
ood/46.wav|is feeling a confidence I've never felt in myself as a subject of desire. At least, not around Carl.
|
||||
ood/47.wav|A beautifully long silence emerges as we both enjoy the sexual tension and chemistry unfolding between us.
|
||||
ood/48.wav|After so many years of trying to manufacture a moment of sensuality and intimacy between us, I am now faced with the fantasy.
|
||||
ood/49.wav|I so dreamed of, but this moment of longing and desire we both share right now.
|
||||
ood/50.wav|is much more arousing than I could have ever imagined. My entire family is in the house a few yards behind the back of this deck chair I sit in.
|
||||
ood/51.wav|Carl is kneeling beside me. He still clutches the small plate of homemade pumpkin pie with maple whipped cream. Carl is more than a neighbor.
|
||||
ood/52.wav|He's a family friend. This moment couldn't possibly be filled with more tension and suspense. It's perfect.
|
||||
ood/53.wav|Finally, I release my hands from behind my head. It looks like I'm about to take the plate from Carl, but I don't.
|
||||
ood/54.wav|Instead, I pinch the sides of my nightie with my fingers. Carl, I say softly, I've got something that I'd love you to try.
|
||||
ood/55.wav|I very slowly start to pull the nightie up my sides so that the hem brushes up my thighs and over my pussy. Let me know your expert thoughts.
|
||||
ood/56.wav|The nightie continues to rise up my body, exposing a very naked and vulnerable me, almost shocked.
|
||||
ood/57.wav|I feel cold air and the moisture building between my legs. Carl places the plate on the ground, but remains still, silent.
|
||||
ood/58.wav|Almost. If this is going to happen here, like this, then he will have to meet me on the other side of this forbidden line.
|
||||
ood/59.wav|I slowly bring my knees out to the side and expose myself fully to him. This should make his impulses harder to resist.
|
||||
ood/60.wav|I see him swallow, but his eyes never leave the gift I am giving him. I need you to tell me if it's sweet enough.
|
||||
ood/61.wav|He then looks me straight in the eyes. Yes, Carl, I want you to taste my pussy. Thank you for listening. For the entire story, please visit audio desires dot com.
|
||||
ood/62.wav|The doorbell rings and yanks me painfully away from my horny reverie. Fuck it, I was really enjoying that flashback. Me and Carl in the backyard.
|
||||
ood/63.wav|Having a secret sexual encounter while my whole family is just inside the house, I can still feel the tension, the excitement.
|
||||
ood/64.wav|The sensation, even after all these years, the presence of his tongue exploring my native vagina.
|
||||
ood/65.wav|Carl is the only man who has so skillfully and tenderly made me orgasm using only his mouth
|
||||
ood/66.wav|For years, I longed for something sensual to take place between me and my sexy guy next door. And when it finally did.
|
||||
ood/67.wav|It was the last time I actually saw Carl. He got a job in another state, and I went traveling abroad for several years.
|
||||
ood/68.wav|I guess everyone holds a fantasy of a neighbor they once had. I certainly do. In my case, though, it's not a fantasy that I hold dear.
|
||||
ood/69.wav|but a vivid memory. It's one of my sexiest memories. I treasure it and nurture it by reliving the moment again and again.
|
||||
ood/70.wav|Each time I revisit that scene in my mind of Carl and I sharing an intimate exchange out the back, I feel my pussy tingle with excitement.
|
||||
ood/71.wav|The thing that makes this memory so delicious is the secrecy behind it all. There's something really hot about pursuing things that are.
|
||||
ood/72.wav|kind of forbidden, about engaging in activities that you know will form a secret to be shared only between you and the other perpetrator.
|
||||
ood/73.wav|My family and Carl's family have lived side by side for as long as I can remember. Their family is beloved to ours. Carl is especially beloved.
|
||||
ood/74.wav|So, if anyone somehow found out that Carl ate my pussy in the backyard here.
|
||||
ood/75.wav|While the whole family was just inside the house finishing dinner? Well, well, I don't know what would happen exactly.
|
||||
ood/76.wav|But no one should know, ever. It has to stay between Carl and me.
|
||||
ood/77.wav|I realize that I've been stroking my panties the whole time I've been thinking about this explicit encounter, and I'm not really surprised.
|
||||
ood/78.wav|Oh crap! I totally forgot that Carl's mom was joining us for dinner. My brother and his wife thought it might be nice to have her over.
|
||||
ood/79.wav|since we are all back home for the holiday. Now that her husband has passed, she lives alone, and Carl lives in another state, so Misses Jones gets lonely.
|
||||
ood/80.wav|I race to the front of the house in a fluster to greet Carl's mom, and I realize that I'm still smelling like my own aroused sex.
|
||||
ood/81.wav|As I turn the knob and fling open the door, my mind is forming the words, Mrs. Jones, how lovely to see you after all these years.
|
||||
ood/82.wav|But when my brain catches up to what my eyes are looking at on our front porch, my heart literally stops for a second or two. It's Carl.
|
||||
ood/83.wav|His beautiful big voice resonates through my entire stilted body. This feeling of surprise is almost traumatic.
|
||||
ood/84.wav|Carl yeah let's just say quite a few. the years have been very kind to him. He hasn't changed a bit.
|
||||
ood/85.wav|His warm brown eyes, his large velvet lips, his football strong arms, his giant sincere smile.
|
||||
ood/86.wav|I'm still motionless as I feel a cloud of pheromones emanate from my body and drift directly into him.
|
||||
ood/87.wav|I offer out my hand, which he happily takes. Then, he pulls me into his body for a giant, nostalgic embrace. I melt into him.
|
||||
ood/88.wav|and try to ignore that I can smell the scent of my own pussy in our handshake. Eventually, the rest of the family join us at the front door to welcome our beloved neighbors.
|
||||
ood/89.wav|We head inside, and the feast gets underway. I tell embarrassing stories about Carl working out in the backyard.
|
||||
ood/90.wav|in front of a mirror, kissing his own muscles. We all loosen up over some delicious wine. Karl is warm, intelligent, and authentic.
|
||||
ood/91.wav|The kind of man I think I could be with, I lose myself in his entertaining stories, and my foot finds its way to his leg as often as it can.
|
||||
ood/92.wav|At one point, I catch myself with one shoe kicked off, and my toes gently resting on him. I like to be touching him.
|
||||
ood/93.wav|When he talks, I can only look directly at his mouth. I feel his kiss on my inner thighs. I feel his teeth pinching my nipples.
|
||||
ood/94.wav|I feel that familiar ache between my legs as my pussy screams at me to jump right on top of Carl.
|
||||
ood/95.wav|and ease his cock deep inside me. These sorts of urges become harder and harder to ignore as the evening meal progresses between dinner and dessert.
|
||||
ood/96.wav|We decide to have some entertainment and some sweet wine. Mom starts playing piano and everyone else finds a spot in the living area to enjoy the show.
|
||||
ood/97.wav|I make my way into the kitchen to start preparing dessert. I'm at the island bench in the middle of the kitchen, cutting the dessert pie into decent pieces.
|
||||
ood/98.wav|when I see Carl's fit body in the doorway. Okay, great. Thanks, Carl. Are you sure? You'll miss the piano playing. Oh, yeah?
|
||||
ood/99.wav|What about? Carl walks over to my side of the island bench. About when you ate my pussy in the backyard? Carl looks down at me, deep in my eyes.
|
||||
ood/100.wav|Wished for what? Carl is searching for the right words. But we both know that there aren't any. We look into each other for a moment.
|
||||
ood/101.wav|while the twinkling of the piano floats in from the next room and the dessert pie lay unattended on the kitchen bench. Then, suddenly, passionately,
|
||||
ood/102.wav|Our two faces are drawn into each other, and our lips lock into a deep kiss that disables all the feeling in my legs.
|
||||
ood/103.wav|Carl holds me tightly, and my fears of falling over into a quivering heap are gone. He grabs me by the ass with a firm hand.
|
||||
ood/104.wav|and pushes my pussy into his stiffened pants. I suck his face with all my might. Carl is rubbing my butt with his fingers.
|
||||
ood/105.wav|Dancing around my anus, and I swear, I can almost hear my own pussy crying out his name. I arch my back slightly.
|
||||
ood/106.wav|tilt my ass upward. He bends slightly at the knees, rub my pussy through the back of my dress. I feel his breath, and he whispers into my ear.
|
||||
ood/107.wav|I tilt my head back. My breathing intensifies. He slowly kisses around my neck and under my chin.
|
||||
ood/108.wav|until his lips have found their way to my other ear. While Carl is feasting on my earlobes, I slide my hand between his cock and my pussy.
|
||||
ood/109.wav|And I start to undo his zipper, something that I've always wished for. I remind him that they are all preoccupied around the piano.
|
||||
ood/110.wav|And before he has a chance to draw my attention to the fact that all our loved ones are in the very next room, and that the only thing he needs to worry about.
|
||||
ood/111.wav|is trying not to come right onto my face while I lick his giant cock from balls to knob. And with that.
|
||||
ood/112.wav|I get down on my knees and unleash the most beautiful, clean, and strong penis my eyes have ever beheld.
|
||||
ood/113.wav|I see a bolt of energy shoot through his shaft, and his cock transforms into its thick, glorious full size.
|
||||
ood/114.wav|I take the briefest of seconds to soak this image in and let it burn into my collection of secret memories about Carl, as promised.
|
||||
ood/115.wav|I allow my tongue the pleasure of a single, long, slow lick from his balls.
|
||||
ood/116.wav|All the way up the smooth sensitive skin of his shaft to his swollen head
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,196 @@
|
||||
wavs/1.wav|Look at that, who are the boxers? Booker. Booker! Okay, just one more? Booker, that was amazing.|1151
|
||||
wavs/2.wav|Off about Lady Comstock. Try the shock jockey. We worked hard enough to get it. None of the prophet's magic is rubbing off on you.|1151
|
||||
wavs/3.wav|That was odd. Daisy can make a change, can't she? Things better for the people here. I'm worried about you. What did you do there?|1151
|
||||
wavs/4.wav|Train up a child in the way he should go. Even when he is old, he will not depart from it. Hey, Booker, I think there's a lock pick over there.|1151
|
||||
wavs/5.wav|If you put a person in a cage, they develop an interest in such things. We are gonna have visitors, Booker! Rosalind Lutece is not my mother, and neither are you.|1151
|
||||
wavs/6.wav|She's either a great hero or the worst of scoundrels, depending on who's doing the telling. Over here! Who are we really helping by getting guns for the Vox Populi?|1151
|
||||
wavs/7.wav|I remember making them. Booker, grab that lock pick. Booker, there's a lock pick over there. How many have you had? I'll keep an eye on you for next time. Booker!|1151
|
||||
wavs/8.wav|You could try forcing it open. Doesn't seem to work very well. Comstock is two decks up in the Prophet's Cabin. It's the Lutece lab. As I said, it's a form of wish fulfillment.|1151
|
||||
wavs/9.wav|Hey, Booker. Slate has the shock jockey, we need to find him. This Tear. I'm not so sure it was a good idea. Can always use more of them.|1151
|
||||
wavs/10.wav|Look at this, my tower. It's only fair they give me a cut of the profits, don't you think? Need more money? Who? You mean.|1151
|
||||
wavs/11.wav|Here's some cash. What for? I get to wear this stylish thimble to cover up my hideous deformity. I hear they're all the rage in Paris. The seed of the prophet.|1151
|
||||
wavs/12.wav|Shall set the throne. He was grooming me, wasn't he? Why? We should look for more foot prints. Keep a look out. I can open that. I can.|1151
|
||||
wavs/13.wav|Look at these, they're amazing! Which one do you like more, this one, or this? I can see them through the doors. You, me, Columbia Song Bird?|1151
|
||||
wavs/14.wav|But sometimes, something's different, yet the same. Do you hear that? It's music! Looks easy enough.|1151
|
||||
wavs/15.wav|Catch, Booker! It almost looks like a real ocean. It's just a set of elaborate pumps and rain catchers. Booker, there's a door over here. Look, a tear. Who sent you?|1151
|
||||
wavs/16.wav|Ready. You know how I said I had plenty of time to read? Well, I tried to figure it out. I read literature on physics and other such things. When you're unconscious on the beach, you.|1151
|
||||
wavs/17.wav|Kept repeating a woman's name, Anna. This could come in handy. You really should pick that up. Booker, come here. They hardly laid a finger on us.|1151
|
||||
wavs/18.wav|It's her. Found this lying around. Her trail must be somewhere. I am not going back to that tower no matter what happens.|1151
|
||||
wavs/19.wav|Song Bird is ready, Booker. This looks important, Booker. Forget. How do you wash away the things that you've done?|1151
|
||||
wavs/20.wav|Hey, don't point that at me. Good. Slate must've taken them. Look. Hurry, Booker, hurry! Booker, the poster. You chose to walk away.|1151
|
||||
wavs/21.wav|It's about Seven Thirty. There are a million, million worlds. All different and all similar. Constants and variables.|1151
|
||||
wavs/22.wav|On your right, I see a tear. Fink Industries. Seems like they're the ones responsible for this shock jockey product. They should be ashamed of themselves.|1151
|
||||
wavs/23.wav|We can pick up some supplies from that machine. If it had a mechanical lock, maybe. It's one of those shock jockey doors. You're wounded! Here!|1151
|
||||
wavs/24.wav|No. He was here. This way. Look over here. Why don't you ring the bell? If he were to take me back. That's death, Mister DeWitt.|1151
|
||||
wavs/25.wav|Or something so like it I cannot tell the difference. I'm out! Shock Jockey. Who needs the power company?|1151
|
||||
wavs/26.wav|Must be because of what's going on with that man's sleigh. The cage shut up tight. Now how are we gonna get to the air ship? Look at this! Mister DeWitt?|1151
|
||||
wavs/27.wav|I don't understand. Why would the twins send us to find three truths? Were the tears somehow related through a kind of quantum field, or were they?|1151
|
||||
wavs/28.wav|Time rots everything, Booker. Even hope. Here, let me. Look.|1151
|
||||
wavs/29.wav|The box of bolts dropped his weapon, you should use it. They're just taking back what's owed to them. It's justice. What the hell was that? Hey Booker?|1151
|
||||
wavs/30.wav|I see a tear. Huh. Go on without me! But in all of ours. Are you alright? That did not look easy.|1151
|
||||
wavs/31.wav|Beyond that gate lies Comstock House. Destroy the siphon? If they play the whole song, he'll come back. Put that away. These seem to be the controls that summon her.|1151
|
||||
wavs/32.wav|I've got salts! Sorry, Booker. He was all I had. Brought me books. And that will take us to Paris.|1151
|
||||
wavs/33.wav|Come on. Do you need ammo? Done. Take this for the bleeding! Okay, catch. Comstock? Huh.|1151
|
||||
wavs/34.wav|So the First Lady is his ship. You hold on to this. I don't know! Give it to me! Booker, salts! Booker, no.|1151
|
||||
wavs/35.wav|Wait, what is that? Forty North by Seventy Four West. That's not Paris, that's New York. That tear will get us access to higher ground. Over here, Booker.|1151
|
||||
wavs/36.wav|One thing I had in that tower was time, Mister Dewitt. Time to study things like geography. I'll try to keep you stocked with both bandages and ammo, but.|1151
|
||||
wavs/37.wav|The right materials aren't always at hand. Let me have a look. Booker, but the thing is, my books said they disappeared several years ago.|1151
|
||||
wavs/38.wav|Are you sure? Hey! Say what you want about Lady Comstock. A woman had an eye for fashion. It'll take some scrounging, but I'll do my best.|1151
|
||||
wavs/39.wav|Cash, Booker. My husband claims the child was created from whole cloth by divine will. I am a believer, but I am not a fool.|1151
|
||||
wavs/40.wav|His bastard shall not be raised under this roof. A guitar. Wish I knew how to play. Might just spell some of the gloom.|1151
|
||||
wavs/41.wav|She's going to kill that child! He's ready, Booker! Look, might be a good idea to lay in some supplies.|1151
|
||||
wavs/42.wav|There's a world of difference between what we see and what is. Strange. I see a tear, Booker. I think we're gonna have visitors. Everything.|1151
|
||||
wavs/43.wav|Above you, Booker! Look out! Handy Man! What does Mister Fink want with us? Looks like this runs exclusively on shock jockey.|1151
|
||||
wavs/44.wav|This is what he meant. Might not be a bad idea to lay in some supplies. Daisy said she was coming here for Fink.|1151
|
||||
wavs/45.wav|There, back in the land of the living. All yours. Don't spend it all in one place. That automaton's weapon is lying over there. Seems like we're fairly well healed, Booker.|1151
|
||||
wavs/46.wav|There. Do you think it's possible to redeem the kind of things that we've done?|1151
|
||||
wavs/47.wav|Mister DeWitt! I can open this if you want. What are you, Mister DeWitt? Some sort of. Hey, there's a lock over there. Hey, Booker!|1151
|
||||
wavs/48.wav|You hear that? Music. It's coming from that tear. Find something soon! The seed of the prophet lay in the womb of Our Lady but for a single week.|1151
|
||||
wavs/49.wav|It's a figure of Comstock now. I found some change. I don't know if I brought us to a world where the Vox had weapons, or I created one.|1151
|
||||
wavs/50.wav|Let's see. How did you do that? Are you interested in gardening, Mister DeWitt? Careful, that doesn't look too safe. Why you? Okay!|1151
|
||||
wavs/51.wav|I see more foot prints. I don't like his look. How are you, Mother? All locked up in there, huh? Looks like you and I have some common ground.|1151
|
||||
wavs/52.wav|No. What happened there? Sure. Careful! Why is it that we never catch a break? The founder of Buddhism spent forty nine days under a Bodhi tree.|1151
|
||||
wavs/53.wav|Until he achieved enlightenment. Hey, Mister DeWitt! That poster. There's another cipher on it. This is in our hands, isn't it? Are you sure, Booker?|1151
|
||||
wavs/54.wav|Did I just bring us to a world where Chen Lin was alive, or did I create it? I told you, I always thought that.|1151
|
||||
wavs/55.wav|My little trick was a form of wish fulfillment. I got my wish. Comstock. I've read about him. They say he can see the future.|1151
|
||||
wavs/56.wav|Booker, sniper rifle! I just can't decide. Lock picks. They have her preserved in an air tight chamber. Her finger prints will get us into Comstock House.|1151
|
||||
wavs/57.wav|You bet. This is going to be fantastic. Take this. This doesn't make any sense.|1151
|
||||
wavs/58.wav|Everything here is a cipher that I understand except for this symbol. It's all right. It's as much a mystery to me as anyone else.|1151
|
||||
wavs/59.wav|Maybe Song Bird knows, but he's not talking. Like what? A window. A window to another world. Most of the time they're dull as dish water.|1151
|
||||
wavs/60.wav|Different colored towel or tea instead of coffee. But sometimes, sometimes I see something amazing and I pull it through.|1151
|
||||
wavs/61.wav|And how has that worked out for you? Booker will find it. Just leave her be. Did you notice? Lin had a bloody nose.|1151
|
||||
wavs/62.wav|I think that's the way down. And why lock me up? The bird is beautiful, and the cage is somber, but there's really something special about it.|1151
|
||||
wavs/63.wav|Booker, the lines are clear! We're gonna have visitors, Booker. You must think me some sort of freak. A girl who can bring dead men back to life.|1151
|
||||
wavs/64.wav|Whose only acquaintance is a giant bird creature. That must seem ridiculous. Where did they take him? Look, a tear.|1151
|
||||
wavs/65.wav|Booker, your nose. She's almost feral. It's like she's a reflection of. I don't know. Catch!|1151
|
||||
wavs/66.wav|You're bleeding! Don't you think it's best if we keep moving? I found a tear. Look, Vox are tearing this place apart. Booker, you've already been.|1151
|
||||
wavs/67.wav|Looks simple enough. Booker, over here. Being dead. Comstock. So the First Lady is his ship. Interesting. You're injured. More of her foot prints.|1151
|
||||
wavs/68.wav|Do you know this artificial beach was built in only six months? But there is. There is something I. Booker. Excuse me?|1151
|
||||
wavs/69.wav|It's the only way we'll find the truth. But my finger. Comstock. Look, it's the hand of the prophet. Comstock's flagship!|1151
|
||||
wavs/70.wav|My finger. Huh. Aren't we the well to do types? You're a liar, Mister Dewitt and a thug, but you're also my only means of reaching Paris.|1151
|
||||
wavs/71.wav|There they are, the tools. Couldn't hurt to stock up. He's coming for you! Over here. The gun smith Chen Lin wanted for known connections to the out law Daisy Fitzroy.|1151
|
||||
wavs/72.wav|Daisy Fitzroy. I've read about her. Books say she's out to tear Columbia from the sky. Is that the last of them? It always has.|1151
|
||||
wavs/73.wav|When I was younger, I used to be excited when I heard it. Flawless Flintlock! It's the newest one in the series. I read it was delayed three times.|1151
|
||||
wavs/74.wav|Looks like we found where your old friend Slate is. Yes. Looks like everything's been impounded at the Good Time Club. Maybe that's where we'll find it.|1151
|
||||
wavs/75.wav|Booker, do you see those tears? We can use them against Slate's men. Thank you. And you were born again as a different man. Mister DeWitt, you didn't go through with it.|1151
|
||||
wavs/76.wav|Ammunition here if you need it. We don't need to. It'll happen all the same. Really? There's a lock. I wonder what's on the other side.|1151
|
||||
wavs/77.wav|Let's stay away from them. It was a fine thing you came along when you did. Soldier's Field, built in nineteen oh three by the hand of our prophet.|1151
|
||||
wavs/78.wav|Nose, it's bleeding. I do not like the looks of that thing. Booker, up there. One of those shock jockey doors.|1151
|
||||
wavs/79.wav|Maybe we should take a look. Booker, wake up. Booker, you don't leave this room until you do. Vending machine? I do not like the looks of this, Booker.|1151
|
||||
wavs/80.wav|Comstock is three decks up, in the Prophet's cabin. Really? Why? I do not like the way they're looking at us. Huh. Because it does.|1151
|
||||
wavs/81.wav|Because it has. Because it will. They're coming. And I won't be locked up again, but. Mister DeWitt. Here, where do you think this goes?|1151
|
||||
wavs/82.wav|Hey, mister! You're gonna get mustard all over your nice suit! This is what the code key's for. Over here. Sure thing. What's going on? Mister DeWitt, I.|1151
|
||||
wavs/83.wav|A tear! Booker, over here. Huh, trouble up ahead. You see it? Interesting. Booker, if we go into this tear.|1151
|
||||
wavs/84.wav|I don't think there's any turning back. Are you sure you want to go now? If I could find some genuine lock picks, I might be able to get this door open.|1151
|
||||
wavs/85.wav|I'm sure I saw some interesting things on the other side. No, it's me, Elizabeth. Are you alright? Booker. This is amazing.|1151
|
||||
wavs/86.wav|How have I never tried this? I can't believe how much I've missed. All right. Booker, look at that.|1151
|
||||
wavs/87.wav|You've done this before, haven't you? Look at that. Tear, right there. Behind you. But I could help. We can't seem to catch a break, Mister Dewitt.|1151
|
||||
wavs/88.wav|Strange. Look at that. What did Slate mean? What did you try to erase? They, well at least she, invented the technology that allows the city to float.|1151
|
||||
wavs/89.wav|I can call Song Bird and Booker. Don't laugh. We better steer clear of them. Oh, no, I'm not Annabelle. Mister DeWitt. Catch, Mister DeWitt.|1151
|
||||
wavs/90.wav|Seems easy enough. I can see a tear. Looks simple enough. Misses Lin, can you tell me who took your husband's tools? Here you go.|1151
|
||||
wavs/91.wav|Booker, there must be a button under the register. I know that place. That's Albert Fink's house. I love his music. I wonder if he's in there.|1151
|
||||
wavs/92.wav|It'll take some scrounging, but I'll do my best. Looks like Fink isn't giving you the job. Should we use this? It's over, right? Please tell me it's over. Is that the code book?|1151
|
||||
wavs/93.wav|Ready and waiting! Hi there, I'm just so angry. I think she's her, but she's also partly me. I'm not even sure I understand it myself.|1151
|
||||
wavs/94.wav|Booker, foot prints. It's done. No. No, it isn't. I think you should see this. Here. Booker, their noses. They're all bleeding.|1151
|
||||
wavs/95.wav|They all lead us to the same place, where it started. No problem. We can't seem to catch a break. Booker, look at this.|1151
|
||||
wavs/96.wav|I'm sorry about what I said at the docks. Calling you a thug? A code book? I wonder where the cipher is. There. Hmm. Hello.|1151
|
||||
wavs/97.wav|Booker, are you afraid of God? What is this? I can do that. If you want to ask me, ask me. You know I?|1151
|
||||
wavs/98.wav|I keep thinking about that dream that you had. New York on fire. There's something about it. The sky line is clear, Booker. Booker, look what I found!|1151
|
||||
wavs/99.wav|Tolls at midnight. Booker, I can get through these bars, but you're too broad. Let me scout ahead, see if there's some way to move forward.|1151
|
||||
wavs/100.wav|Chen Lin. Gun smith. Oh my god! And Madame Lutece. He used me to power that device! He opened up some kind of tear!|1151
|
||||
wavs/101.wav|Worry. Just keep telling yourself this is only a game. We can solve it. Super dork's more like it.|1152
|
||||
wavs/102.wav|This isn't an eating contest, Joey, this is dangerous. Silly? I think you look just great!|1152
|
||||
wavs/103.wav|Yugi, did you check me out? I look way too good to be sittin' at home. Where's Joey, anyway? Come on, don't be such a wimp.|1152
|
||||
wavs/105.wav|Could still be friends outside it. If he hadn't loaned me his star chips, I might never have made it to the final round. I owe him a very great debt.|1152
|
||||
wavs/107.wav|Even without my tricks, I can still duel with the best of 'em! And now I'll lay down a second card which will finish my turn.|1152
|
||||
wavs/108.wav|Gotcha. Thanks Yugi, I wanted you to attack. Your Gaia ran smack into my mirror wall which cuts any of your monsters attack power in half.|1152
|
||||
wavs/109.wav|As soon as your monster attacked, the mirror wall rose up to protect my Harpy Lady! Your fierce knight met an equal attack from its own reflection!|1152
|
||||
wavs/110.wav|Guess it's my turn again. High fashioned for Harpy Lady. Cyber Shield.|1152
|
||||
wavs/111.wav|Not much else you can do, is there, Yugi, since I've left you no way to attack? My turn now.|1152
|
||||
wavs/112.wav|Rose Whip to raise my monsters attack! Now you're Imps gonna feel my Harpy's sting!|1152
|
||||
wavs/113.wav|That's nothing, Yugi. Stick around, the fun's just beginning. Promised you'd try harder, Yugi, but I see now that's not going to happen!|1152
|
||||
wavs/114.wav|What have we here? Well, with this card, my Harpy combo won't be quite complete.|1152
|
||||
wavs/117.wav|You don't even have your favorite card the Dark Magician left. What are you gonna do now? if this is how you treat your friends, I can't wait to see how you treat your enemies.|1152
|
||||
wavs/118.wav|I'm being kind, not stupid. What's up? If you guys have enough star chips to get into the castle, why are you hanging out here?|1152
|
||||
wavs/119.wav|Now go on, Yugi. You know I owe you, so take them. Earth to Yugi. Star chips at twelve o'clock.|1152
|
||||
wavs/120.wav|What, are my star chips not good enough for you? Come on, chicken boy, duel me for them now. Fine! Then I'll keep them!|1152
|
||||
wavs/121.wav|And your friends can wipe your nose all the way back to the nursery! Grow up! Oh, I understand your friend lost one lousy duel and now he's too chicken to play again! Isn't that right?|1152
|
||||
wavs/122.wav|Come on, be serious! An amateur like you wouldn't stand a chance against me! Are you sure you wanna duel me?|1152
|
||||
wavs/123.wav|Hun, it's sweet you standing up for Yugi and all, but sweet doesn't win duels. Now I'll ask you one last time.|1152
|
||||
wavs/124.wav|I play Harpy Lady! And I'll lay this too. Your fairy turned to dust!|1152
|
||||
wavs/125.wav|You know, Tea, if you're trembling with fear after just the first round, maybe you should quit right here?|1152
|
||||
wavs/126.wav|Another of these cutesy cards? Come on, what Are we having a duel or a pageant?|1152
|
||||
wavs/127.wav|Sorry hun, but I activated my magic card. The Rose Whip, a personal favorite. It gives my harpy three hundred extra attack!|1152
|
||||
wavs/128.wav|You call it quits right now. This isn't gonna get any easier, you know? Just give up and go back to cheerleading!|1152
|
||||
wavs/129.wav|Please, if this is the start of some friendship rant, just save it. I've heard all your lame speeches before, and from that look on Yugi's face.|1152
|
||||
wavs/130.wav|I'd say he has too. You're just a little girl who's accidentally stumbled into the big leagues, but whatever, you'll learn the hard way.|1152
|
||||
wavs/131.wav|Harpy's Feather Duster. My turn, hub, and I'm playing this face down!|1152
|
||||
wavs/132.wav|In fact, it was so stirring I almost feel the need to throw up! Fine with me!|1152
|
||||
wavs/133.wav|It's not like I don't have magic cards too! Cyber Shield! It was nothing that Tea wouldn't have been able to beat anyway, really.|1152
|
||||
wavs/134.wav|But wait, I'll also play this de spell. No more hope, no more faith, no more chances!|1152
|
||||
wavs/135.wav|Don't you know the rules yet, Tea? Since I've flipped your Magician of Faith over with my attack, you get a card back from the graveyard.|1152
|
||||
wavs/136.wav|I mean, how can you seriously hope to beat me when you don't know the rules? Look honey, I'm sure that everyone's really impressed that you've lasted this long.|1152
|
||||
wavs/137.wav|But all you're doing is delaying the inevitable! Come on, what you're doing is pointless. Yugi's already given up on himself.|1152
|
||||
wavs/138.wav|You're not gonna be able to keep fighting for him. He has to fight for himself! He has to stand up to anyone who dares to get in his way!|1152
|
||||
wavs/139.wav|And whatever's going on in his head, Tea, Yugi has to deal with it on his own. I surrender, Tea. I don't have the cards to win.|1152
|
||||
wavs/140.wav|Face it, Tea, Yugi's checked out! He's given up! He doesn't care about this match and he doesn't care about you! Nothing's worth the humiliation you're going through.|1152
|
||||
wavs/141.wav|You may have a tendency to run at the mouth, but you've got a lot of spunk. Give me your best shot! Whatever. I didn't need these anyway.|1152
|
||||
wavs/142.wav|Don't rub it in, Tea, Harpy Lady was the best monster I had and seeing as how you beat her, there's really no point in me going on.|1152
|
||||
wavs/143.wav|Some cards just aren't worth playing, huh, Yugi? It's all because of that obnoxious punk Joey! I can't believe such an amateur beat me!|1152
|
||||
wavs/144.wav|I don't get it. Trashing hotshot duelists is usually as fun as a fall clearance sale. Why can't I enjoy it anymore?|1152
|
||||
wavs/145.wav|I've got to get even with that grinning gutter punk! Bon voyage, loser! Funny, I thought I already knocked you on your Jurassic butt.|1152
|
||||
wavs/146.wav|You think I'm gonna waste another minute with a pea brain like you? Beat it, dino breath! From one of these like you who think that by dueling a chick, they'll score some easy stars.|1152
|
||||
wavs/147.wav|I've only lost once, but once I find that punk kid Joey, it's pay back. I'd love to see you try and. Okay, Rex, I'll duel you.|1152
|
||||
wavs/148.wav|If you do something for me first. How are you, Joseph? Glad to see me? So Joey, is Yugi still fighting all your battles for you?|1152
|
||||
wavs/149.wav|Everyone knows if Yugi wasn't there to hold your hand, you wouldn't have beat me. Isn't that right, Yugi? I'm waiting for your answer, Joey.|1152
|
||||
wavs/150.wav|Oh really? Then I propose he steps out of your shadow here and now! if Joey thinks he's so tough, let's see him play for himself!|1152
|
||||
wavs/151.wav|Think you have the guts to step up and face the duelist I've arranged for you?|1152
|
||||
wavs/152.wav|If Little Yugi does any of his back seat dueling, then Joey is disqualified and the match automatically goes to.|1152
|
||||
wavs/153.wav|What do you say, Joey? This is your big chance to prove yourself. Or are you going to back out? So what's it gonna be?|1152
|
||||
wavs/154.wav|You going to run off with your friend or start acting like a real duelist? Raptor, watch that Time Wizard!|1152
|
||||
wavs/155.wav|Rex, you big dino dummy! You're either a champ or a trump. Cut this guy loose, he's fashion challenged and deserves to be crushed in the games.|1152
|
||||
wavs/156.wav|I'll crush you all eventually. The name's Mai. Call your superior! Get him on the phone right now!|1152
|
||||
wavs/157.wav|This is truly truly outrageous. You expect a lady like me to stay in this dump without even a shower?|1152
|
||||
wavs/158.wav|Who do you think you are? Really? Could I see it? It's beautiful! You must be quite a strong card player.|1152
|
||||
wavs/159.wav|Really? I love duel monsters. How about we play a game? Okay, then cut the cards.|1152
|
||||
wavs/160.wav|Please? Let me try. Tell you what, If you win, I'll give you a kiss.|1152
|
||||
wavs/161.wav|If I win, you agree to clear out of the room for the rest of the trip. Okay? The first card is Shadow of Eyes.|1152
|
||||
wavs/162.wav|The second card is Harpy's Lady, then Elegant Egotist, followed by Cyber Shield.|1152
|
||||
wavs/163.wav|This is my own card technique. I always know what cards I have and can pick any one I like at any time. So, go ahead and deal 'em, Rex.|1152
|
||||
wavs/164.wav|Pretty big turnout for this thing. Oh, this is so exciting! I wonder whose butt I should kick first in this tournament?|1152
|
||||
wavs/165.wav|If it isn't Rex Raptor and Weevil. I thought I smelled something. Some duelists just never change.|1152
|
||||
wavs/166.wav|Hmph. So you finally came, Yugi. Very funny, Yugi, but you should know by now that I don't need to use tricky tactics to win.|1152
|
||||
wavs/167.wav|I've been studying this new game just so that I can defeat you. Let's duel, Yugi! No mercy, Yugi.|1152
|
||||
wavs/168.wav|There's no holding back. You'll see that I've got much better. Are you thinking of taking it easy on me?|1152
|
||||
wavs/169.wav|I'll show you techniques that you haven't even imagined! Is this the best you can do?|1152
|
||||
wavs/170.wav|Ha ha ha ha! Prepare to lose! There's nothing I hate more than weak losers, Yugi.|1152
|
||||
wavs/171.wav|Aren't you going to attack me? You're no fun. Failure's calling. Will you accept the charges? Don't think I'll give up that easily.|1152
|
||||
wavs/172.wav|Huh, this is nothing. I'm not backing down from any challenge. Did you really think I was going to submit?|1152
|
||||
wavs/173.wav|I never give up no matter how bad it looks. Yugi, my dream is to defeat you.|1152
|
||||
wavs/174.wav|I'll see how good you are at this new game. Ha ha. Let's hope this is an honorable duel. Just what do you think you're doing?|1152
|
||||
wavs/175.wav|Take it easy, will ya? Oh! I can't believe this is happening! Nice attack! A critical hit!|1152
|
||||
wavs/176.wav|Oh, spunky, That's beginner's luck, that's all. La de da! There's no problem if you don't destroy my monster.|1152
|
||||
wavs/177.wav|Now you're getting serious. That's no way to treat a lady. You're starting to annoy me. Take it easy, will ya?|1152
|
||||
wavs/178.wav|Ha ha. Don't think I'll forget this. Ha ha! This duel's practically over! You don't crack easily, do you?|1152
|
||||
wavs/179.wav|Too bad, Yugi, but it looks like I am going to win this duel. Can you survive this? Ha ha! I hope you love surprises!|1152
|
||||
wavs/180.wav|Defeat or be defeated. Those are the only two options. Why let up when I'm having so much fun? Ah ha ha ha ha!|1152
|
||||
wavs/181.wav|I'm one with my monsters! Ha ha ha, feast on this! You shouldn't have taken me so lightly!|1152
|
||||
wavs/182.wav|Perish! Fall before my power! I'll win with this technique! Slice him to pieces, my Harpy!|1152
|
||||
wavs/183.wav|Ha ha ha. I hope you don't get whiplash! My Harpy Lady's sisters, unleash your fiery blast!|1152
|
||||
wavs/184.wav|Ha ha ha ha. You will be punished! My dear pet, get rid of him for me!|1152
|
||||
wavs/185.wav|Against my servants overwhelming strength. What can you possibly do? I'll show you what fusion can do!|1152
|
||||
wavs/186.wav|I'll defeat you with the combined power of my monsters! My monster becomes more beautiful after it evolves!|1152
|
||||
wavs/187.wav|Now, taste the power of my evolved monster! You should never underestimate an evolved monster!|1152
|
||||
wavs/188.wav|My my your monsters are weaker than I expected. Like taking candy from a baby. Ha ha ha. You're such a fool!|1152
|
||||
wavs/189.wav|You've lost half your monsters! Isn't it time to call it quits? Ha ha. You can't stop me!|1152
|
||||
wavs/190.wav|That's what you get for thinking you've won! Ah, how disappointing. I thought you were much better than this.|1152
|
||||
wavs/191.wav|What a pathetic way to lose, Yugi! Ha ha ha. What a wonderful duel it was! This duel is mine!|1152
|
||||
wavs/192.wav|Didn't think you'd let me attack your symbol so easily! Did you get a lobotomy and lose all your skills, Little Yugi?|1152
|
||||
wavs/193.wav|Yes, chalk one up for Mai! Oh, tough! But things will only get tougher for you.|1152
|
||||
wavs/194.wav|I'm just testing you out. Huh. I'll still get you, Yugi. That's what you think. I'll regain the advantage soon enough.|1152
|
||||
wavs/195.wav|Ha ha. Ah! Yugi's in the lead! All my lovely creatures are destroyed!|1152
|
||||
wavs/196.wav|No way! They're all gone! Yes, it was even though I lost, I don't regret anything.|1152
|
||||
wavs/197.wav|Am I going to lose? My symbol? Oh no, I completely forgot about it!|1152
|
||||
wavs/198.wav|Can't be! You are aiming directly for it! Oh my. I didn't know this could happen. I guess tonight is ladies night.|1152
|
||||
wavs/199.wav|Wait, what's going on? I didn't hear anything about this! Ouch! What is that? This is horrible! What Is this?|1152
|
||||
wavs/200.wav|Wait a second! Give me time to think! So I take damage there. I'd better be careful. Damage? Is it because of that location?|1152
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
val/250.wav|Rockets, be careful! I can't find anything for you! Get away! He's got Rockets! Turn around! Booker! The lines are clear! Handy man, kill it!|1151
|
||||
val/251.wav|To the left! Watch out, Patriot! Go, go, go! Booker, he'll help us! We can use him against the box fleet!|1151
|
||||
val/252.wav|Crow, no! Let me go! Get your hands off of me! Let me go! I've got medicine!|1151
|
||||
val/253.wav|Booker, you're hurt! Ammo, Booker! Done! Stop it! Watch out! Handy man! I'll see what else I can find! Look, Mister DeWitt!|1151
|
||||
val/254.wav|You don't want to be here when he gets here! Just a minute! I'm getting dressed! Go! You've gotta go! He's coming towards you! They're on the barge!|1151
|
||||
val/255.wav|There's no way out, trust me, I've looked! Stop it, you're too impatient, that's enough! Fire man, Booker! You're a monster! Booker, look. In case you need it!|1151
|
||||
val/256.wav|You could try forcing it open. Booker, Song bird's ready. Just drop me off if you want to. Handy man, over there! Booker, which tear do you want me to open?|1151
|
||||
val/257.wav|Be careful, there's a crow! I found ammo! I think I can help! Tell me which tear to open! There's nothing around! I'm not ready! I see her!|1151
|
||||
val/258.wav|Over here, Booker! There's a tear! We can take that sky line to the Prophet's cabin! Aim for his gears! Salts, catch! A tear over there!|1151
|
||||
val/259.wav|Which way? Ammo, take it! Up this way! Hey, take your time! I'm fine down here. Booker, behind you! The balcony, Booker!|1151
|
||||
val/260.wav|Look out! More of them! Look! I can't find anything! I owe you an apology! Comstock used me to bring you back, but.|1151
|
||||
val/261.wav|I brought back a version of you from the reality that I had built up in my own head! He pretended to love you, like he pretended to love me!|1151
|
||||
val/262.wav|Booker, balcony! Oh my god! Over there! Fire man! Over there! Flak Cannon! I've got you covered! You tell me, what did he mean about my finger?|1151
|
||||
val/263.wav|Watch the balcony! I can open these tears for you! Here! Ammo! To the right! What?! I can help! Booker, a crow! Booker! Look up!|1151
|
||||
val/264.wav|Booker, rockets! Bring us the girl and wipe away the debt! Take this! There's a patriot! I am not going with you!|1151
|
||||
val/265.wav|I can open this! I've got ammo if you need it! Down here! Booker, flak cannon! Get away from me! He's down! Finally!|1151
|
||||
val/266.wav|Booker, the gears! Booker, salts! I'm looking, hold on! Who are you? Why did you come here? I need more time! Sniper, get down!|1151
|
||||
val/267.wav|Booker, Song bird's ready! I'm looking! Get up, Booker! Get up! Booker! Handy man! There's a tear! Just give the word! They must be duds!|1151
|
||||
val/268.wav|Booker! Behind you! Booker, call him in. Fire man, Booker, careful! I think we're gonna have visitors. I see a tear, Booker!|1151
|
||||
val/269.wav|Watch out for the barge! No, no, no, Booker! Supply's up! Watch out, fire men! The right, Booker! Booker, take this! There's nothing left!|1151
|
||||
val/270.wav|Handy man, watch out! You bet! Booker, see that tear? Right, Booker! Booker, you're left! Left, Booker! Watch out, crow! On it!|1151
|
||||
val/271.wav|Rocket, Booker! I've got your back! Patriot, kill it! No, no, no! No, I'm getting that hand. Look, handy man!|1151
|
||||
val/272.wav|Salts, Booker! Booker! I have salts! Booker! What are you doing? Booker, here! Booker! Over there! The box!|1151
|
||||
val/273.wav|Booker, the Roof top! I had a role in this catastrophe! If you want to pretend that we're purely innocents in this, then that's your prerogative, but. Blow you! I have a better idea.|1151
|
||||
val/274.wav|Catch! Black cannon over there! Catch! We've gotta get out of here! I haven't found anything yet! Take it! The heart! Hit him in the heart! What is all this?|1151
|
||||
val/275.wav|They were watching me all this time. Why? Why did they put me in here? What am I? What am I?|1151
|
||||
val/276.wav|I just want to get out of this city. Please. You need this! Handy man, Booker! Booker! The sky line, Booker. On it!|1151
|
||||
val/277.wav|There's no way up from here! Do not attempt to follow me, Mister Dewitt! On the sky line! I'm looking for more! Booker, he's ready! They're on the balcony!|1151
|
||||
val/278.wav|The barge, Booker! Here you go! Okay! Up on the roof top! That's all I've got! Tell me where to send him. Patriot! Over there! There's supplies when you need them!|1151
|
||||
val/279.wav|Wah! Watch out, Black Cannon! Keep your eyes open! Ammo! Catch! Look out, he's charging! Why? What did I do to them?|1151
|
||||
val/280.wav|Down below! Booker the barge! Fire man! I found salts! Take cover! There's a handy man! Bottle salts!|1151
|
||||
val/281.wav|Take this, hurry! Patriot, Booker! Fire man over there! There's more of them! Look out!|1151
|
||||
val/282.wav|Mister DeWitt, look! Tears, Booker! Ammo Booker! I'll try to keep you stocked!|1151
|
||||
val/283.wav|Fifty percent of everything people earn here goes right to Comstock as a tithe. They're just right for each other, aren't they? Booker, we should be careful.|1151
|
||||
val/284.wav|You just can't remember it. Oh, I loved those stories when I was a kid. They are a bit off putting.|1151
|
||||
val/285.wav|I know you hate me for not being your daughter, and I hated you for not being my mother. Alright, let's see. Type.|1151
|
||||
val/286.wav|Three letters to spell the voice. Look at this. Booker, take this rifle. Booker, this is Misses Lin.|1151
|
||||
val/287.wav|I don't know. Is that possible? But the child took ill, and Our Lady prayed for the prophet's heir day and night. In this world, you are a martyr.|1151
|
||||
val/288.wav|And where will we get these weapons? This is my mother's diary. Why would Slate have it? They shut down Gondola access to the Hall of Heroes.|1151
|
||||
val/289.wav|These men. Seems easy. This is between me. I think you should see this. Booker, see this? I can see all the doors.|1151
|
||||
val/290.wav|And what's behind all the doors. And behind one of them, we must forgive each other.|1151
|
||||
val/291.wav|Because there is one far worse than you or I. Who are you? Comstock led the Columbian troops to Peeking and.|1151
|
||||
val/292.wav|How do you figure they'd know you'd be coming? Hey, Mister DeWitt, I'll see what I can do. Stay away! Comstock had a child.|1151
|
||||
val/293.wav|My book's never mentioned anything about a child. Can the sky line help? There's the launch panel. Booker, look, the shrine. Because he is not going to have long to use it.|1151
|
||||
val/294.wav|We'll give it a whirl. Found his hair. We can take that skyline to the Prophet's cabin. I hope Comstock got what he wanted from me.|1151
|
||||
val/295.wav|I used to open them all the time in my tower. I'm sorry, I shouldn't have pried. Look! You need ammo? Har har.|1151
|
||||
val/296.wav|Until I grew up, I hated him because he was my warden, but he's just Comstock's pet, isn't he? Just like me. The broken clock.|1151
|
||||
val/297.wav|She deserved whatever Comstock did to her. That's one quarter of the pods ejected! No, let's keep an eye out. Here it is, Booker.|1151
|
||||
val/298.wav|Booker! Another gun ship on the left! What could people have done to deserve to be locked up in a place like this? Pankertons.|1151
|
||||
val/299.wav|Weren't they the ones they'd call in to settle things when the workers took to striking? Eventually you'll give him what he wants. Well, the man's got an ego.|1151
|
||||
val/300.wav|But he killed you both. I guess it's from me. Hey, see this? Why is one bath room for colors and the other for whites? Why are they dropping so slowly?|1151
|
||||
val/201.wav|What damage? Is it that place's fault? I thought you had guts, but I guess I was wrong.|1152
|
||||
val/202.wav|Huh? What? You're giving up already? What a loser. Stop day dreaming, Yugi!|1152
|
||||
val/203.wav|Doh. Don't tell me you already don't know what to do next. Hurry up. You snooze, you lose.|1152
|
||||
val/204.wav|Are trying to annoy me? Ha ha ha. I can't wait forever. Get moving, will ya?|1152
|
||||
val/205.wav|Stop stalling for time. That's so lame. Yugi, It's not polite to keep a lady waiting.|1152
|
||||
val/206.wav|All my hard work's finally paid off! You should have practiced more. Too bad, Yugi. Yugi, there are two ways of losing.|1152
|
||||
val/207.wav|One way is to lose everything. I'm going to learn from this loss so that I can become stronger and I will achieve my dream in the end.|1152
|
||||
val/208.wav|Good luck in the tournament, Yugi! Yugioh! Ha ha. Well, let's get started!|1152
|
||||
val/209.wav|You'll find out what girl power's all about! No man can ever beat me! I'll crush you!|1152
|
||||
val/210.wav|I can see all your cards, kid. It's my turn! I'll take down all you losers.|1152
|
||||
val/211.wav|The other way is to lose a battle in order to win the war. And I will beat you in the future. Ha ha ha. You have another thing coming!|1152
|
||||
val/212.wav|Just wait until I strike you with my own critical hits. But you will fall eventually, they all do.|1152
|
||||
val/213.wav|Are you really the King of Games? You're still an amateur when it comes to Capsule Monsters! Because I prepared a great one just for you!|1152
|
||||
@@ -0,0 +1,100 @@
|
||||
LJ022-0023.wav|ðɪ ˌoʊvɚwˈɛlmɪŋ mədʒˈɔːɹᵻɾi ʌv pˈiːpəl ɪn ðɪs kˈʌntɹi nˈoʊ hˌaʊ tə sˈɪft ðə wˈiːt fɹʌmðə tʃˈæf ɪn wʌt ðeɪ hˈɪɹ ænd wʌt ðeɪ ɹˈiːd .|0
|
||||
LJ043-0030.wav|ɪf sˈʌmbɑːdi dˈɪd ðˈæt tə mˌiː , ɐ lˈaʊsi tɹˈɪk lˈaɪk ðˈæt , tə tˈeɪk maɪ wˈaɪf ɐwˈeɪ , ænd ˈɔːl ðə fˈɜːnɪtʃɚ , aɪ wʊd biː mˈæd æz hˈɛl , tˈuː .|0
|
||||
LJ005-0201.wav|ˌæzˌɪz ʃˈoʊn baɪ ðə ɹᵻpˈoːɹt ʌvðə kəmˈɪʃənɚz tʊ ɪŋkwˈaɪɚɹ ˌɪntʊ ðə stˈeɪt ʌvðə mjuːnˈɪsɪpəl kˌɔːɹpɚɹˈeɪʃənz ɪn ˈeɪtiːn θˈɜːɾi fˈaɪv .|0
|
||||
LJ001-0110.wav|ˈiːvən ðə kˈæslɑːn tˈaɪp wɛn ɛnlˈɑːɹdʒd ʃˈoʊz ɡɹˈeɪt ʃˈɔːɹtkʌmɪŋz ɪn ðɪs ɹᵻspˈɛkt :|0
|
||||
LJ003-0345.wav|ˈɔːl ðə kəmˈɪɾi kʊd dˈuː ɪn ðɪs ɹᵻspˈɛkt wʌz tə θɹˈoʊ ðə ɹᵻspˌɑːnsəbˈɪlɪɾi ˌɔn ˈʌðɚz .|0
|
||||
LJ007-0154.wav|ðiːz pˈʌndʒənt ænd wˈɛl ɡɹˈaʊndᵻd stɹˈɪktʃɚz ɐplˈaɪd wɪð stˈɪl ɡɹˈeɪɾɚ fˈoːɹs tə ðɪ ʌŋkənvˈɪktᵻd pɹˈɪzənɚ , ðə mˈæn hˌuː kˈeɪm tə ðə pɹˈɪzən ˈɪnəsənt , ænd stˈɪl ʌŋkəntˈæmᵻnˌeɪɾᵻd ,|0
|
||||
LJ018-0098.wav|ænd ɹˈɛkəɡnˌaɪzd æz wˈʌn ʌvðə fɹˈiːkwɛntɚz ʌvðə bˈoʊɡəs lˈɔː stˈeɪʃənɚz . hɪz ɚɹˈɛst lˈɛd tə ðæt ʌv ˈʌðɚz .|0
|
||||
LJ047-0044.wav|ˈɑːswəld wʌz , haʊˈɛvɚ , wˈɪlɪŋ tə dɪskˈʌs hɪz kˈɑːntækts wɪð sˈoʊviət ɐθˈɔːɹɪɾiz . hiː dᵻnˈaɪd hˌævɪŋ ˌɛni ɪnvˈɑːlvmənt wɪð sˈoʊviət ɪntˈɛlɪdʒəns ˈeɪdʒənsiz|0
|
||||
LJ031-0038.wav|ðə fˈɜːst fɪzˈɪʃən tə sˈiː ðə pɹˈɛzɪdənt æt pˈɑːɹklənd hˈɑːspɪɾəl wʌz dˈɑːktɚ . tʃˈɑːɹlz dʒˈeɪ . kˈæɹɪkˌoʊ , ɐ ɹˈɛzᵻdənt ɪn dʒˈɛnɚɹəl sˈɜːdʒɚɹi .|0
|
||||
LJ048-0194.wav|dˈʊɹɹɪŋ ðə mˈɔːɹnɪŋ ʌv noʊvˈɛmbɚ twˈɛnti tˈuː pɹˈaɪɚ tə ðə mˈoʊɾɚkˌeɪd .|0
|
||||
LJ049-0026.wav|ˌɔn əkˈeɪʒən ðə sˈiːkɹᵻt sˈɜːvɪs hɐzbɪn pɚmˈɪɾᵻd tə hæv ɐn ˈeɪdʒənt ɹˈaɪdɪŋ ɪnðə pˈæsɪndʒɚ kəmpˈɑːɹtmənt wɪððə pɹˈɛzɪdənt .|0
|
||||
LJ004-0152.wav|ɔːlðˈoʊ æt mˈɪstɚ . bˈʌkstənz vˈɪzɪt ɐ nˈuː dʒˈeɪl wʌz ɪn pɹˈɑːsɛs ʌv ɪɹˈɛkʃən , ðə fˈɜːst stˈɛp təwˈɔːɹdz ɹᵻfˈɔːɹm sˈɪns hˈaʊɚdz vˌɪzɪtˈeɪʃən ɪn sˈɛvəntˌiːn sˈɛvənti fˈoːɹ .|0
|
||||
LJ008-0278.wav|ɔːɹ ðˈɛɹz mˌaɪt biː wˈʌn ʌv mˈɛni , ænd ɪt mˌaɪt biː kənsˈɪdɚd nˈɛsᵻsɚɹi tə dˈɑːlɚ mˌeɪk ɐn ɛɡzˈæmpəl.dˈɑːlɚ|0
|
||||
LJ043-0002.wav|ðə wˈɔːɹəŋ kəmˈɪʃən ɹᵻpˈoːɹt . baɪ ðə pɹˈɛzɪdənts kəmˈɪʃən ɔnðɪ ɐsˌæsᵻnˈeɪʃən ʌv pɹˈɛzɪdənt kˈɛnədi . tʃˈæptɚ sˈɛvən . lˈiː hˈɑːɹvi ˈɑːswəld :|0
|
||||
LJ009-0114.wav|mˈɪstɚ . wˈeɪkfiːld wˈaɪndz ˈʌp hɪz ɡɹˈæfɪk bˌʌt sˈʌmwʌt sɛnsˈeɪʃənəl ɐkˈaʊnt baɪ dᵻskɹˈaɪbɪŋ ɐnˈʌðɚ ɹᵻlˈɪdʒəs sˈɜːvɪs , wˌɪtʃ mˈeɪ ɐpɹˈoʊpɹɪˌeɪtli biː ɪnsˈɜːɾᵻd hˈɪɹ .|0
|
||||
LJ028-0506.wav|ɐ mˈɑːdɚn ˈɑːɹɾɪst wʊdhɐv dˈɪfɪkˌʌlti ɪn dˌuːɪŋ sˈʌtʃ ˈækjʊɹət wˈɜːk .|0
|
||||
LJ050-0168.wav|wɪððə pɚtˈɪkjʊlɚ pˈɜːpəsᵻz ʌvðɪ ˈeɪdʒənsi ɪnvˈɑːlvd . ðə kəmˈɪʃən ɹˈɛkəɡnˌaɪzᵻz ðæt ðɪs ɪz ɐ kˌɑːntɹəvˈɜːʃəl ˈɛɹiə|0
|
||||
LJ039-0223.wav|ˈɑːswəldz mɚɹˈiːn tɹˈeɪnɪŋ ɪn mˈɑːɹksmənʃˌɪp , hɪz ˈʌðɚ ɹˈaɪfəl ɛkspˈiəɹɪəns ænd hɪz ɪstˈæblɪʃt fəmˌɪliˈæɹɪɾi wɪð ðɪs pɚtˈɪkjʊlɚ wˈɛpən|0
|
||||
LJ029-0032.wav|ɐkˈoːɹdɪŋ tʊ oʊdˈɑːnəl , kwˈoʊt , wiː hæd ɐ mˈoʊɾɚkˌeɪd wɛɹˈɛvɚ kplˈʌsplʌs wˌɪtʃ hɐdbɪn bˌɪn hˈeɪstili sˈʌmənd fɚðə ðə pˈɜːpəs wiː wˈɛnt , ˈɛnd kwˈoʊt .|0
|
||||
LJ031-0070.wav|dˈɑːktɚ . klˈɑːɹk , hˌuː mˈoʊst klˈoʊsli əbzˈɜːvd ðə hˈɛd wˈuːnd ,|0
|
||||
LJ034-0198.wav|jˈuːɪnz , hˌuː wʌz ɔnðə saʊθwˈɛst kˈɔːɹnɚɹ ʌv ˈɛlm ænd hjˈuːstən stɹˈiːts tˈɛstᵻfˌaɪd ðæt hiː kʊd nˌɑːt dᵻskɹˈaɪb ðə mˈæn hiː sˈɔː ɪnðə wˈɪndoʊ .|0
|
||||
LJ026-0068.wav|ˈɛnɚdʒi ˈɛntɚz ðə plˈænt , tʊ ɐ smˈɔːl ɛkstˈɛnt ,|0
|
||||
LJ039-0075.wav|wˈʌns juː nˈoʊ ðæt juː mˈʌst pˌʊt ðə kɹˈɔshɛɹz ɔnðə tˈɑːɹɡɪt ænd ðæt ɪz ˈɔːl ðæt ɪz nˈɛsᵻsɚɹi .|0
|
||||
LJ004-0096.wav|ðə fˈeɪɾəl kˈɑːnsɪkwənsᵻz wˈɛɹɑːf mˌaɪt biː pɹɪvˈɛntᵻd ɪf ðə dʒˈʌstɪsᵻz ʌvðə pˈiːs wɜː djˈuːli ˈɔːθɚɹˌaɪzd|0
|
||||
LJ005-0014.wav|spˈiːkɪŋ ˌɔn ɐ dᵻbˈeɪt ˌɔn pɹˈɪzən mˈæɾɚz , hiː dᵻklˈɛɹd ðˈæt|0
|
||||
LJ012-0161.wav|hiː wʌz ɹᵻpˈoːɹɾᵻd tə hæv fˈɔːlən ɐwˈeɪ tʊ ɐ ʃˈædoʊ .|0
|
||||
LJ018-0239.wav|hɪz dˌɪsɐpˈɪɹəns ɡˈeɪv kˈʌlɚ ænd sˈʌbstəns tʊ ˈiːvəl ɹᵻpˈoːɹts ɔːlɹˌɛdi ɪn sˌɜːkjʊlˈeɪʃən ðætðə wɪl ænd kənvˈeɪəns əbˌʌv ɹᵻfˈɜːd tuː|0
|
||||
LJ019-0257.wav|hˈɪɹ ðə tɹˈɛd wˈiːl wʌz ɪn jˈuːs , ðɛɹ sˈɛljʊlɚ kɹˈæŋks , ɔːɹ hˈɑːɹd lˈeɪbɚ məʃˈiːnz .|0
|
||||
LJ028-0008.wav|juː tˈæp dʒˈɛntli wɪð jʊɹ hˈiːl əpˌɑːn ðə ʃˈoʊldɚɹ ʌvðə dɹˈoʊmdɚɹi tʊ ˈɜːdʒ hɜːɹ ˈɔn .|0
|
||||
LJ024-0083.wav|ðɪs plˈæn ʌv mˈaɪn ɪz nˈoʊ ɐtˈæk ɔnðə kˈoːɹt ;|0
|
||||
LJ042-0129.wav|nˈoʊ nˈaɪt klˈʌbz ɔːɹ bˈoʊlɪŋ ˈælɪz , nˈoʊ plˈeɪsᵻz ʌv ɹˌɛkɹiːˈeɪʃən ɛksˈɛpt ðə tɹˈeɪd jˈuːniən dˈænsᵻz . aɪ hæv hæd ɪnˈʌf .|0
|
||||
LJ036-0103.wav|ðə pəlˈiːs ˈæskt hˌɪm wˈɛðɚ hiː kʊd pˈɪk ˈaʊt hɪz pˈæsɪndʒɚ fɹʌmðə lˈaɪnʌp .|0
|
||||
LJ046-0058.wav|dˈʊɹɹɪŋ hɪz pɹˈɛzɪdənsi , fɹˈæŋklɪn dˈiː . ɹˈoʊzəvˌɛlt mˌeɪd ˈɔːlmoʊst fˈoːɹ hˈʌndɹɪd dʒˈɜːniz ænd tɹˈævəld mˈoːɹ ðɐn θɹˈiː hˈʌndɹɪd fˈɪfti θˈaʊzənd mˈaɪlz .|0
|
||||
LJ014-0076.wav|hiː wʌz sˈiːn ˈæftɚwɚdz smˈoʊkɪŋ ænd tˈɔːkɪŋ wɪð hɪz hˈoʊsts ɪn ðɛɹ bˈæk pˈɑːɹlɚ , ænd nˈɛvɚ sˈiːn ɐɡˈɛn ɐlˈaɪv .|0
|
||||
LJ002-0043.wav|lˈɔŋ nˈæɹoʊ ɹˈuːmz wˈʌn θˈɜːɾi sˈɪks fˈiːt , sˈɪks twˈɛnti θɹˈiː fˈiːt , ænd ðɪ ˈeɪtθ ˈeɪtiːn ,|0
|
||||
LJ009-0076.wav|wiː kˈʌm tə ðə sˈɜːmən .|0
|
||||
LJ017-0131.wav|ˈiːvən wɛn ðə hˈaɪ ʃˈɛɹɪf hæd tˈoʊld hˌɪm ðɛɹwˌʌz nˈoʊ pˌɑːsəbˈɪlɪɾi əvɚ ɹᵻpɹˈiːv , ænd wɪðˌɪn ɐ fjˈuː ˈaʊɚz ʌv ˌɛksɪkjˈuːʃən .|0
|
||||
LJ046-0184.wav|bˌʌt ðɛɹ ɪz ɐ sˈɪstəm fɚðɪ ɪmˈiːdɪət nˌoʊɾɪfɪkˈeɪʃən ʌvðə sˈiːkɹᵻt sˈɜːvɪs baɪ ðə kənfˈaɪnɪŋ ˌɪnstɪtˈuːʃən wɛn ɐ sˈʌbdʒɛkt ɪz ɹᵻlˈiːst ɔːɹ ɛskˈeɪps .|0
|
||||
LJ014-0263.wav|wˌɛn ˈʌðɚ plˈɛʒɚz pˈɔːld hiː tˈʊk ɐ θˈiəɾɚ , ænd pˈoʊzd æz ɐ mjuːnˈɪfɪsənt pˈeɪtɹən ʌvðə dɹəmˈæɾɪk ˈɑːɹt .|0
|
||||
LJ042-0096.wav|ˈoʊld ɛkstʃˈeɪndʒ ɹˈeɪt ɪn ɐdˈɪʃən tə hɪz fˈæktɚɹi sˈælɚɹi ʌv ɐpɹˈɑːksɪmətli ˈiːkwəl ɐmˈaʊnt|0
|
||||
LJ049-0050.wav|hˈɪl hæd bˈoʊθ fˈiːt ɔnðə kˈɑːɹ ænd wʌz klˈaɪmɪŋ ɐbˈoːɹd tʊ ɐsˈɪst pɹˈɛzɪdənt ænd mˈɪsɪz . kˈɛnədi .|0
|
||||
LJ019-0186.wav|sˈiːɪŋ ðæt sˈɪns ðɪ ɪstˈæblɪʃmənt ʌvðə sˈɛntɹəl kɹˈɪmɪnəl kˈoːɹt , nˈuːɡeɪt ɹᵻsˈiːvd pɹˈɪzənɚz fɔːɹ tɹˈaɪəl fɹʌm sˈɛvɹəl kˈaʊntiz ,|0
|
||||
LJ028-0307.wav|ðˈɛn lˈɛt twˈɛnti dˈeɪz pˈæs , ænd æt ðɪ ˈɛnd ʌv ðæt tˈaɪm stˈeɪʃən nˌɪɹ ðə tʃˈældæsəŋ ɡˈeɪts ɐ bˈɑːdi ʌv fˈoːɹ θˈaʊzənd .|0
|
||||
LJ012-0235.wav|wˌaɪl ðeɪ wɜːɹ ɪn ɐ stˈeɪt ʌv ɪnsˌɛnsəbˈɪlɪɾi ðə mˈɜːdɚ wʌz kəmˈɪɾᵻd .|0
|
||||
LJ034-0053.wav|ɹˈiːtʃt ðə sˈeɪm kəŋklˈuːʒən æz lætˈoʊnə ðætðə pɹˈɪnts fˈaʊnd ɔnðə kˈɑːɹtənz wɜː ðoʊz ʌv lˈiː hˈɑːɹvi ˈɑːswəld .|0
|
||||
LJ014-0030.wav|ðiːz wɜː dˈæmnətˌoːɹi fˈækts wˌɪtʃ wˈɛl səpˈoːɹɾᵻd ðə pɹˌɑːsɪkjˈuːʃən .|0
|
||||
LJ015-0203.wav|bˌʌt wɜː ðə pɹɪkˈɔːʃənz tˈuː mˈɪnɪt , ðə vˈɪdʒɪləns tˈuː klˈoʊs təbi ᵻlˈuːdᵻd ɔːɹ ˌoʊvɚkˈʌm ?|0
|
||||
LJ028-0093.wav|bˌʌt hɪz skɹˈaɪb ɹˈoʊt ɪɾ ɪnðə mˈænɚ kˈʌstəmˌɛɹi fɚðə skɹˈaɪbz ʌv ðoʊz dˈeɪz tə ɹˈaɪt ʌv ðɛɹ ɹˈɔɪəl mˈæstɚz .|0
|
||||
LJ002-0018.wav|ðɪ ɪnˈædɪkwəsi ʌvðə dʒˈeɪl wʌz nˈoʊɾɪst ænd ɹᵻpˈoːɹɾᵻd əpˌɑːn ɐɡˈɛn ænd ɐɡˈɛn baɪ ðə ɡɹˈænd dʒˈʊɹɹiz ʌvðə sˈɪɾi ʌv lˈʌndən ,|0
|
||||
LJ028-0275.wav|æt lˈæst , ɪnðə twˈɛntiəθ mˈʌnθ ,|0
|
||||
LJ012-0042.wav|wˌɪtʃ hiː kˈɛpt kənsˈiːld ɪn ɐ hˈaɪdɪŋ plˈeɪs wɪð ɐ tɹˈæp dˈoːɹ dʒˈʌst ˌʌndɚ hɪz bˈɛd .|0
|
||||
LJ011-0096.wav|hiː mˈæɹid ɐ lˈeɪdi ˈɔːlsoʊ bᵻlˈɔŋɪŋ tə ðə səsˈaɪəɾi ʌv fɹˈɛndz , hˌuː bɹˈɔːt hˌɪm ɐ lˈɑːɹdʒ fˈɔːɹtʃʊn , wˈɪtʃ , ænd hɪz ˈoʊn mˈʌni , hiː pˌʊt ˌɪntʊ ɐ sˈɪɾi fˈɜːm ,|0
|
||||
LJ036-0077.wav|ɹˈɑːdʒɚ dˈiː . kɹˈeɪɡ , ɐ dˈɛpjuːɾi ʃˈɛɹɪf ʌv dˈæləs kˈaʊnti ,|0
|
||||
LJ016-0318.wav|ˈʌðɚɹ əfˈɪʃəlz , ɡɹˈeɪt lˈɔɪɚz , ɡˈʌvɚnɚz ʌv pɹˈɪzənz , ænd tʃˈæplɪnz səpˈoːɹɾᵻd ðɪs vjˈuː .|0
|
||||
LJ013-0164.wav|hˌuː kˈeɪm fɹʌm hɪz ɹˈuːm ɹˈɛdi dɹˈɛst , ɐ səspˈɪʃəs sˈɜːkəmstˌæns , æz hiː wʌz ˈɔːlweɪz lˈeɪt ɪnðə mˈɔːɹnɪŋ .|0
|
||||
LJ027-0141.wav|ɪz klˈoʊsli ɹᵻpɹədˈuːst ɪnðə lˈaɪf hˈɪstɚɹi ʌv ɛɡzˈɪstɪŋ dˈɪɹ . ɔːɹ , ɪn ˈʌðɚ wˈɜːdz ,|0
|
||||
LJ028-0335.wav|ɐkˈoːɹdɪŋli ðeɪ kəmˈɪɾᵻd tə hˌɪm ðə kəmˈænd ʌv ðɛɹ hˈoʊl ˈɑːɹmi , ænd pˌʊt ðə kˈiːz ʌv ðɛɹ sˈɪɾi ˌɪntʊ hɪz hˈændz .|0
|
||||
LJ031-0202.wav|mˈɪsɪz . kˈɛnədi tʃˈoʊz ðə hˈɑːspɪɾəl ɪn bəθˈɛzdə fɚðɪ ˈɔːtɑːpsi bɪkˈʌz ðə pɹˈɛzɪdənt hæd sˈɜːvd ɪnðə nˈeɪvi .|0
|
||||
LJ021-0145.wav|fɹʌm ðoʊz wˈɪlɪŋ tə dʒˈɔɪn ɪn ɪstˈæblɪʃɪŋ ðɪs hˈoʊpt fɔːɹ pˈiəɹɪəd ʌv pˈiːs ,|0
|
||||
LJ016-0288.wav|dˈɑːlɚ mˈuːlɚ , mˈuːlɚ , hiːz ðə mˈæn , dˈɑːlɚ tˈɪl ɐ daɪvˈɜːʒən wʌz kɹiːˈeɪɾᵻd baɪ ðɪ ɐpˈɪɹəns ʌvðə ɡˈæloʊz , wˌɪtʃ wʌz ɹᵻsˈiːvd wɪð kəntˈɪnjuːəs jˈɛlz .|0
|
||||
LJ028-0081.wav|jˈɪɹz lˈeɪɾɚ , wˌɛn ðɪ ˌɑːɹkiːˈɑːlədʒˌɪsts kʊd ɹˈɛdili dɪstˈɪŋɡwɪʃ ðə fˈɔls fɹʌmðə tɹˈuː ,|0
|
||||
LJ018-0081.wav|hɪz dᵻfˈɛns bˌiːɪŋ ðæt hiː hæd ɪntˈɛndᵻd tə kəmˈɪt sˈuːɪsˌaɪd , bˌʌt ðˈæt , ɔnðɪ ɐpˈɪɹəns ʌv ðɪs ˈɑːfɪsɚ hˌuː hæd ɹˈɔŋd hˌɪm ,|0
|
||||
LJ021-0066.wav|təɡˌɛðɚ wɪð ɐ ɡɹˈeɪt ˈɪŋkɹiːs ɪnðə pˈeɪɹoʊlz , ðɛɹ hɐz kˈʌm ɐ səbstˈænʃəl ɹˈaɪz ɪnðə tˈoʊɾəl ʌv ɪndˈʌstɹɪəl pɹˈɑːfɪts|0
|
||||
LJ009-0238.wav|ˈæftɚ ðɪs ðə ʃˈɛɹɪfs sˈɛnt fɔːɹ ɐnˈʌðɚ ɹˈoʊp , bˌʌt ðə spɛktˈeɪɾɚz ˌɪntəfˈɪɹd , ænd ðə mˈæn wʌz kˈæɹid bˈæk tə dʒˈeɪl .|0
|
||||
LJ005-0079.wav|ænd ɪmpɹˈuːv ðə mˈɔːɹəlz ʌvðə pɹˈɪzənɚz , ænd ʃˌæl ɪnʃˈʊɹ ðə pɹˈɑːpɚ mˈɛʒɚɹ ʌv pˈʌnɪʃmənt tə kənvˈɪktᵻd əfˈɛndɚz .|0
|
||||
LJ035-0019.wav|dɹˈoʊv tə ðə nɔːɹθwˈɛst kˈɔːɹnɚɹ ʌv ˈɛlm ænd hjˈuːstən , ænd pˈɑːɹkt ɐpɹˈɑːksɪmətli tˈɛn fˈiːt fɹʌmðə tɹˈæfɪk sˈɪɡnəl .|0
|
||||
LJ036-0174.wav|ðɪs ɪz ðɪ ɐpɹˈɑːksɪmət tˈaɪm hiː ˈɛntɚd ðə ɹˈuːmɪŋhˌaʊs , ɐkˈoːɹdɪŋ tʊ ˈɜːliːn ɹˈɑːbɚts , ðə hˈaʊskiːpɚ ðˈɛɹ .|0
|
||||
LJ046-0146.wav|ðə kɹaɪtˈiəɹɪə ɪn ɪfˈɛkt pɹˈaɪɚ tə noʊvˈɛmbɚ twˈɛnti tˈuː , nˈaɪntiːn sˈɪksti θɹˈiː , fɔːɹ dɪtˈɜːmɪnɪŋ wˈɛðɚ tʊ ɐksˈɛpt mətˈɪɹiəl fɚðə pˌiːˌɑːɹɹˈɛs dʒˈɛnɚɹəl fˈaɪlz|0
|
||||
LJ017-0044.wav|ænd ðə dˈiːpɪst æŋzˈaɪəɾi wʌz fˈɛlt ðætðə kɹˈaɪm , ɪf kɹˈaɪm ðˈɛɹ hɐdbɪn , ʃˌʊd biː bɹˈɔːt hˈoʊm tʊ ɪts pˈɜːpɪtɹˌeɪɾɚ .|0
|
||||
LJ017-0070.wav|bˌʌt hɪz spˈoːɹɾɪŋ ˌɑːpɚɹˈeɪʃənz dɪdnˌɑːt pɹˈɑːspɚ , ænd hiː bɪkˌeɪm ɐ nˈiːdi mˈæn , ˈɔːlweɪz dɹˈɪvən tə dˈɛspɚɹət stɹˈeɪts fɔːɹ kˈæʃ .|0
|
||||
LJ014-0020.wav|hiː wʌz sˈuːn ˈæftɚwɚdz ɚɹˈɛstᵻd ˌɔn səspˈɪʃən , ænd ɐ sˈɜːtʃ ʌv hɪz lˈɑːdʒɪŋz bɹˈɔːt tə lˈaɪt sˈɛvɹəl ɡˈɑːɹmənts sˈætʃɚɹˌeɪɾᵻd wɪð blˈʌd ;|0
|
||||
LJ016-0020.wav|hiː nˈɛvɚ ɹˈiːtʃt ðə sˈɪstɚn , bˌʌt fˈɛl bˈæk ˌɪntʊ ðə jˈɑːɹd , ˈɪndʒɚɹɪŋ hɪz lˈɛɡz sᵻvˈɪɹli .|0
|
||||
LJ045-0230.wav|wˌɛn hiː wʌz fˈaɪnəli ˌæpɹihˈɛndᵻd ɪnðə tˈɛksəs θˈiəɾɚ . ɔːlðˈoʊ ɪɾ ɪz nˌɑːt fˈʊli kɚɹˈɑːbɚɹˌeɪɾᵻd baɪ ˈʌðɚz hˌuː wɜː pɹˈɛzənt ,|0
|
||||
LJ035-0129.wav|ænd ʃiː mˈʌstɐv ɹˈʌn dˌaʊn ðə stˈɛɹz ɐhˈɛd ʌv ˈɑːswəld ænd wʊd pɹˈɑːbəbli hæv sˈiːn ɔːɹ hˈɜːd hˌɪm .|0
|
||||
LJ008-0307.wav|ˈæftɚwɚdz ɛkspɹˈɛs ɐ wˈɪʃ tə mˈɜːdɚ ðə ɹᵻkˈoːɹdɚ fɔːɹ hˌævɪŋ kˈɛpt ðˌɛm sˌoʊ lˈɔŋ ɪn səspˈɛns .|0
|
||||
LJ008-0294.wav|nˌɪɹli ɪndˈɛfɪnətli dᵻfˈɜːd .|0
|
||||
LJ047-0148.wav|ˌɔn ɑːktˈoʊbɚ twˈɛnti fˈaɪv ,|0
|
||||
LJ008-0111.wav|ðeɪ ˈɛntɚd ɐ dˈɑːlɚ stˈoʊŋ kˈoʊld ɹˈuːm , dˈɑːlɚɹ ænd wɜː pɹˈɛzəntli dʒˈɔɪnd baɪ ðə pɹˈɪzənɚ .|0
|
||||
LJ034-0042.wav|ðæt hiː kʊd ˈoʊnli tˈɛstᵻfˌaɪ wɪð sˈɜːtənti ðætðə pɹˈɪnt wʌz lˈɛs ðɐn θɹˈiː dˈeɪz ˈoʊld .|0
|
||||
LJ037-0234.wav|mˈɪsɪz . mˈɛɹi bɹˈɑːk , ðə wˈaɪf əvə mɪkˈænɪk hˌuː wˈɜːkt æt ðə stˈeɪʃən , wʌz ðɛɹ æt ðə tˈaɪm ænd ʃiː sˈɔː ɐ wˈaɪt mˈeɪl ,|0
|
||||
LJ040-0002.wav|tʃˈæptɚ sˈɛvən . lˈiː hˈɑːɹvi ˈɑːswəld : bˈækɡɹaʊnd ænd pˈɑːsᵻbəl mˈoʊɾɪvz , pˈɑːɹt wˌʌn .|0
|
||||
LJ045-0140.wav|ðɪ ˈɑːɹɡjuːmənts hiː jˈuːzd tə dʒˈʌstᵻfˌaɪ hɪz jˈuːs ʌvðɪ ˈeɪliəs sədʒˈɛst ðæt ˈɑːswəld mˌeɪhɐv kˈʌm tə θˈɪŋk ðætðə hˈoʊl wˈɜːld wʌz bᵻkˈʌmɪŋ ɪnvˈɑːlvd|0
|
||||
LJ012-0035.wav|ðə nˈʌmbɚ ænd nˈeɪmz ˌɔn wˈɑːtʃᵻz , wɜː kˈɛɹfəli ɹᵻmˈuːvd ɔːɹ əblˈɪɾɚɹˌeɪɾᵻd ˈæftɚ ðə ɡˈʊdz pˈæst ˌaʊɾəv hɪz hˈændz .|0
|
||||
LJ012-0250.wav|ɔnðə sˈɛvənθ dʒuːlˈaɪ , ˈeɪtiːn θˈɜːɾi sˈɛvən ,|0
|
||||
LJ016-0179.wav|kəntɹˈæktᵻd wɪð ʃˈɛɹɪfs ænd kənvˈiːnɚz tə wˈɜːk baɪ ðə dʒˈɑːb .|0
|
||||
LJ016-0138.wav|æɾə dˈɪstəns fɹʌmðə pɹˈɪzən .|0
|
||||
LJ027-0052.wav|ðiːz pɹˈɪnsɪpəlz ʌv həmˈɑːlədʒi ɑːɹ ᵻsˈɛnʃəl tʊ ɐ kɚɹˈɛkt ɪntˌɜːpɹɪtˈeɪʃən ʌvðə fˈækts ʌv mɔːɹfˈɑːlədʒi .|0
|
||||
LJ031-0134.wav|ˌɔn wˈʌn əkˈeɪʒən mˈɪsɪz . dʒˈɑːnsən , ɐkˈʌmpənid baɪ tˈuː sˈiːkɹᵻt sˈɜːvɪs ˈeɪdʒənts , lˈɛft ðə ɹˈuːm tə sˈiː mˈɪsɪz . kˈɛnədi ænd mˈɪsɪz . kˈɑːnæli .|0
|
||||
LJ019-0273.wav|wˌɪtʃ sˌɜː dʒˈɑːʃjuːə dʒˈɛb tˈoʊld ðə kəmˈɪɾi hiː kənsˈɪdɚd ðə pɹˈɑːpɚɹ ˈɛlɪmənts ʌv pˈiːnəl dˈɪsɪplˌɪn .|0
|
||||
LJ014-0110.wav|æt ðə fˈɜːst ðə bˈɑːksᵻz wɜːɹ ɪmpˈaʊndᵻd , ˈoʊpənd , ænd fˈaʊnd tə kəntˈeɪn mˈɛnɪəv oʊkˈɑːnɚz ɪfˈɛkts .|0
|
||||
LJ034-0160.wav|ˌɔn bɹˈɛnənz sˈʌbsᵻkwənt sˈɜːʔn̩ aɪdˈɛntɪfɪkˈeɪʃən ʌv lˈiː hˈɑːɹvi ˈɑːswəld æz ðə mˈæn hiː sˈɔː fˈaɪɚ ðə ɹˈaɪfəl .|0
|
||||
LJ038-0199.wav|ᵻlˈɛvən . ɪf aɪɐm ɐlˈaɪv ænd tˈeɪkən pɹˈɪzənɚ ,|0
|
||||
LJ014-0010.wav|jˈɛt hiː kʊd nˌɑːt ˌoʊvɚkˈʌm ðə stɹˈeɪndʒ fˌæsᵻnˈeɪʃən ɪt hˈæd fɔːɹ hˌɪm , ænd ɹᵻmˈeɪnd baɪ ðə sˈaɪd ʌvðə kˈɔːɹps tˈɪl ðə stɹˈɛtʃɚ kˈeɪm .|0
|
||||
LJ033-0047.wav|aɪ nˈoʊɾɪst wɛn aɪ wɛnt ˈaʊt ðætðə lˈaɪt wʌz ˈɔn , ˈɛnd kwˈoʊt ,|0
|
||||
LJ040-0027.wav|hiː wʌz nˈɛvɚ sˈæɾɪsfˌaɪd wɪð ˈɛnɪθˌɪŋ .|0
|
||||
LJ048-0228.wav|ænd ˈʌðɚz hˌuː wɜː pɹˈɛzənt sˈeɪ ðæt nˈoʊ ˈeɪdʒənt wʌz ɪnˈiːbɹɪˌeɪɾᵻd ɔːɹ ˈæktᵻd ɪmpɹˈɑːpɚli .|0
|
||||
LJ003-0111.wav|hiː wʌz ɪŋ kˈɑːnsɪkwəns pˌʊt ˌaʊɾəv ðə pɹətˈɛkʃən ʌv ðɛɹ ɪntˈɜːnəl lˈɔː , ˈɛnd kwˈoʊt . ðɛɹ kˈoʊd wʌzɐ sˈʌbdʒɛkt ʌv sˌʌm kjˌʊɹɹɪˈɔsɪɾi .|0
|
||||
LJ008-0258.wav|lˈɛt mˌiː ɹᵻtɹˈeɪs maɪ stˈɛps , ænd spˈiːk mˈoːɹ ɪn diːtˈeɪl ʌvðə tɹˈiːtmənt ʌvðə kəndˈɛmd ɪn ðoʊz blˈʌdθɜːsti ænd bɹˈuːɾəli ɪndˈɪfɹənt dˈeɪz ,|0
|
||||
LJ029-0022.wav|ðɪ ɚɹˈɪdʒɪnəl plˈæŋ kˈɔːld fɚðə pɹˈɛzɪdənt tə spˈɛnd ˈoʊnli wˈʌn dˈeɪ ɪnðə stˈeɪt , mˌeɪkɪŋ wˈɜːlwɪnd vˈɪzɪts tə dˈæləs , fˈɔːɹt wˈɜːθ , sˌæn æntˈoʊnɪˌoʊ , ænd hjˈuːstən .|0
|
||||
LJ004-0045.wav|mˈɪstɚ . stˈɜːdʒᵻz bˈoːɹn , sˌɜː dʒˈeɪmz mˈækɪntˌɑːʃ , sˌɜː dʒˈeɪmz skˈɑːɹlɪt , ænd wˈɪljəm wˈɪlbɚfˌoːɹs .|0
|
||||
@@ -0,0 +1,554 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9adb7bd1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# StyleTTS 2 Demo (LJSpeech)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6108384d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Utils"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "96e173bf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import torch\n",
|
||||
"torch.manual_seed(0)\n",
|
||||
"torch.backends.cudnn.benchmark = False\n",
|
||||
"torch.backends.cudnn.deterministic = True\n",
|
||||
"\n",
|
||||
"import random\n",
|
||||
"random.seed(0)\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"np.random.seed(0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "da84c60f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%cd .."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5a3ddcc8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load packages\n",
|
||||
"import time\n",
|
||||
"import random\n",
|
||||
"import yaml\n",
|
||||
"from munch import Munch\n",
|
||||
"import numpy as np\n",
|
||||
"import torch\n",
|
||||
"from torch import nn\n",
|
||||
"import torch.nn.functional as F\n",
|
||||
"import torchaudio\n",
|
||||
"import librosa\n",
|
||||
"from nltk.tokenize import word_tokenize\n",
|
||||
"\n",
|
||||
"from models import *\n",
|
||||
"from utils import *\n",
|
||||
"from text_utils import TextCleaner\n",
|
||||
"textclenaer = TextCleaner()\n",
|
||||
"\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bbdc04c0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"device = 'cuda' if torch.cuda.is_available() else 'cpu'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "00ee05e1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"to_mel = torchaudio.transforms.MelSpectrogram(\n",
|
||||
" n_mels=80, n_fft=2048, win_length=1200, hop_length=300)\n",
|
||||
"mean, std = -4, 4\n",
|
||||
"\n",
|
||||
"def length_to_mask(lengths):\n",
|
||||
" mask = torch.arange(lengths.max()).unsqueeze(0).expand(lengths.shape[0], -1).type_as(lengths)\n",
|
||||
" mask = torch.gt(mask+1, lengths.unsqueeze(1))\n",
|
||||
" return mask\n",
|
||||
"\n",
|
||||
"def preprocess(wave):\n",
|
||||
" wave_tensor = torch.from_numpy(wave).float()\n",
|
||||
" mel_tensor = to_mel(wave_tensor)\n",
|
||||
" mel_tensor = (torch.log(1e-5 + mel_tensor.unsqueeze(0)) - mean) / std\n",
|
||||
" return mel_tensor\n",
|
||||
"\n",
|
||||
"def compute_style(ref_dicts):\n",
|
||||
" reference_embeddings = {}\n",
|
||||
" for key, path in ref_dicts.items():\n",
|
||||
" wave, sr = librosa.load(path, sr=24000)\n",
|
||||
" audio, index = librosa.effects.trim(wave, top_db=30)\n",
|
||||
" if sr != 24000:\n",
|
||||
" audio = librosa.resample(audio, sr, 24000)\n",
|
||||
" mel_tensor = preprocess(audio).to(device)\n",
|
||||
"\n",
|
||||
" with torch.no_grad():\n",
|
||||
" ref = model.style_encoder(mel_tensor.unsqueeze(1))\n",
|
||||
" reference_embeddings[key] = (ref.squeeze(1), audio)\n",
|
||||
" \n",
|
||||
" return reference_embeddings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7b9cecbe",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Load models"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "64fc4c0f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load phonemizer\n",
|
||||
"import phonemizer\n",
|
||||
"global_phonemizer = phonemizer.backend.EspeakBackend(language='en-us', preserve_punctuation=True, with_stress=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "48e7b644",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"config = yaml.safe_load(open(\"Models/LJSpeech/config.yml\"))\n",
|
||||
"\n",
|
||||
"# load pretrained ASR model\n",
|
||||
"ASR_config = config.get('ASR_config', False)\n",
|
||||
"ASR_path = config.get('ASR_path', False)\n",
|
||||
"text_aligner = load_ASR_models(ASR_path, ASR_config)\n",
|
||||
"\n",
|
||||
"# load pretrained F0 model\n",
|
||||
"F0_path = config.get('F0_path', False)\n",
|
||||
"pitch_extractor = load_F0_models(F0_path)\n",
|
||||
"\n",
|
||||
"# load BERT model\n",
|
||||
"from Utils.PLBERT.util import load_plbert\n",
|
||||
"BERT_path = config.get('PLBERT_dir', False)\n",
|
||||
"plbert = load_plbert(BERT_path)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ffc18cf7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model = build_model(recursive_munch(config['model_params']), text_aligner, pitch_extractor, plbert)\n",
|
||||
"_ = [model[key].eval() for key in model]\n",
|
||||
"_ = [model[key].to(device) for key in model]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "64529d5c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"params_whole = torch.load(\"Models/LJSpeech/epoch_2nd_00100.pth\", map_location='cpu')\n",
|
||||
"params = params_whole['net']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "895d9706",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for key in model:\n",
|
||||
" if key in params:\n",
|
||||
" print('%s loaded' % key)\n",
|
||||
" try:\n",
|
||||
" model[key].load_state_dict(params[key])\n",
|
||||
" except:\n",
|
||||
" from collections import OrderedDict\n",
|
||||
" state_dict = params[key]\n",
|
||||
" new_state_dict = OrderedDict()\n",
|
||||
" for k, v in state_dict.items():\n",
|
||||
" name = k[7:] # remove `module.`\n",
|
||||
" new_state_dict[name] = v\n",
|
||||
" # load params\n",
|
||||
" model[key].load_state_dict(new_state_dict, strict=False)\n",
|
||||
"# except:\n",
|
||||
"# _load(params[key], model[key])\n",
|
||||
"_ = [model[key].eval() for key in model]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c1a59db2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from Modules.diffusion.sampler import DiffusionSampler, ADPM2Sampler, KarrasSchedule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e30985ab",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"sampler = DiffusionSampler(\n",
|
||||
" model.diffusion.diffusion,\n",
|
||||
" sampler=ADPM2Sampler(),\n",
|
||||
" sigma_schedule=KarrasSchedule(sigma_min=0.0001, sigma_max=3.0, rho=9.0), # empirical parameters\n",
|
||||
" clamp=False\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b803110e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Synthesize speech"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "24655f46",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# synthesize a text\n",
|
||||
"text = ''' StyleTTS 2 is a text-to-speech model that leverages style diffusion and adversarial training with large speech language models to achieve human-level text-to-speech synthesis. '''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ca57469c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def inference(text, noise, diffusion_steps=5, embedding_scale=1):\n",
|
||||
" text = text.strip()\n",
|
||||
" text = text.replace('\"', '')\n",
|
||||
" ps = global_phonemizer.phonemize([text])\n",
|
||||
" ps = word_tokenize(ps[0])\n",
|
||||
" ps = ' '.join(ps)\n",
|
||||
"\n",
|
||||
" tokens = textclenaer(ps)\n",
|
||||
" tokens.insert(0, 0)\n",
|
||||
" tokens = torch.LongTensor(tokens).to(device).unsqueeze(0)\n",
|
||||
" \n",
|
||||
" with torch.no_grad():\n",
|
||||
" input_lengths = torch.LongTensor([tokens.shape[-1]]).to(tokens.device)\n",
|
||||
" text_mask = length_to_mask(input_lengths).to(tokens.device)\n",
|
||||
"\n",
|
||||
" t_en = model.text_encoder(tokens, input_lengths, text_mask)\n",
|
||||
" bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())\n",
|
||||
" d_en = model.bert_encoder(bert_dur).transpose(-1, -2) \n",
|
||||
"\n",
|
||||
" s_pred = sampler(noise, \n",
|
||||
" embedding=bert_dur[0].unsqueeze(0), num_steps=diffusion_steps,\n",
|
||||
" embedding_scale=embedding_scale).squeeze(0)\n",
|
||||
"\n",
|
||||
" s = s_pred[:, 128:]\n",
|
||||
" ref = s_pred[:, :128]\n",
|
||||
"\n",
|
||||
" d = model.predictor.text_encoder(d_en, s, input_lengths, text_mask)\n",
|
||||
"\n",
|
||||
" x, _ = model.predictor.lstm(d)\n",
|
||||
" duration = model.predictor.duration_proj(x)\n",
|
||||
" duration = torch.sigmoid(duration).sum(axis=-1)\n",
|
||||
" pred_dur = torch.round(duration.squeeze()).clamp(min=1)\n",
|
||||
"\n",
|
||||
" pred_dur[-1] += 5\n",
|
||||
"\n",
|
||||
" pred_aln_trg = torch.zeros(input_lengths, int(pred_dur.sum().data))\n",
|
||||
" c_frame = 0\n",
|
||||
" for i in range(pred_aln_trg.size(0)):\n",
|
||||
" pred_aln_trg[i, c_frame:c_frame + int(pred_dur[i].data)] = 1\n",
|
||||
" c_frame += int(pred_dur[i].data)\n",
|
||||
"\n",
|
||||
" # encode prosody\n",
|
||||
" en = (d.transpose(-1, -2) @ pred_aln_trg.unsqueeze(0).to(device))\n",
|
||||
" F0_pred, N_pred = model.predictor.F0Ntrain(en, s)\n",
|
||||
" out = model.decoder((t_en @ pred_aln_trg.unsqueeze(0).to(device)), \n",
|
||||
" F0_pred, N_pred, ref.squeeze().unsqueeze(0))\n",
|
||||
" \n",
|
||||
" return out.squeeze().cpu().numpy()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d438ef4f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Basic synthesis (5 diffusion steps)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d3d7f7d5",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"start = time.time()\n",
|
||||
"noise = torch.randn(1,1,256).to(device)\n",
|
||||
"wav = inference(text, noise, diffusion_steps=5, embedding_scale=1)\n",
|
||||
"rtf = (time.time() - start) / (len(wav) / 24000)\n",
|
||||
"print(f\"RTF = {rtf:5f}\")\n",
|
||||
"import IPython.display as ipd\n",
|
||||
"display(ipd.Audio(wav, rate=24000))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2d5d9df0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### With higher diffusion steps (more diverse)\n",
|
||||
"Since the sampler is ancestral, the higher the stpes, the more diverse the samples are, with the cost of slower synthesis speed."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a10129fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"start = time.time()\n",
|
||||
"noise = torch.randn(1,1,256).to(device)\n",
|
||||
"wav = inference(text, noise, diffusion_steps=10, embedding_scale=1)\n",
|
||||
"rtf = (time.time() - start) / (len(wav) / 24000)\n",
|
||||
"print(f\"RTF = {rtf:5f}\")\n",
|
||||
"import IPython.display as ipd\n",
|
||||
"display(ipd.Audio(wav, rate=24000))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1877ea15",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Speech expressiveness\n",
|
||||
"The following section recreates the samples shown in [Section 6](https://styletts2.github.io/#emo) of the demo page."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4c4777b7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### With embedding_scale=1\n",
|
||||
"This is the classifier-free guidance scale. The higher the scale, the more conditional the style is to the input text and hence more emotional. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c29ea2f0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"texts = {}\n",
|
||||
"texts['Happy'] = \"We are happy to invite you to join us on a journey to the past, where we will visit the most amazing monuments ever built by human hands.\"\n",
|
||||
"texts['Sad'] = \"I am sorry to say that we have suffered a severe setback in our efforts to restore prosperity and confidence.\"\n",
|
||||
"texts['Angry'] = \"The field of astronomy is a joke! Its theories are based on flawed observations and biased interpretations!\"\n",
|
||||
"texts['Surprised'] = \"I can't believe it! You mean to tell me that you have discovered a new species of bacteria in this pond?\"\n",
|
||||
"\n",
|
||||
"for k,v in texts.items():\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav = inference(v, noise, diffusion_steps=10, embedding_scale=1)\n",
|
||||
" print(k + \": \")\n",
|
||||
" display(ipd.Audio(wav, rate=24000, normalize=False))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3c89499f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### With embedding_scale=2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f73be3aa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"texts = {}\n",
|
||||
"texts['Happy'] = \"We are happy to invite you to join us on a journey to the past, where we will visit the most amazing monuments ever built by human hands.\"\n",
|
||||
"texts['Sad'] = \"I am sorry to say that we have suffered a severe setback in our efforts to restore prosperity and confidence.\"\n",
|
||||
"texts['Angry'] = \"The field of astronomy is a joke! Its theories are based on flawed observations and biased interpretations!\"\n",
|
||||
"texts['Surprised'] = \"I can't believe it! You mean to tell me that you have discovered a new species of bacteria in this pond?\"\n",
|
||||
"\n",
|
||||
"for k,v in texts.items():\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav = inference(v, noise, diffusion_steps=10, embedding_scale=2) # embedding_scale=2 for more pronounced emotion\n",
|
||||
" print(k + \": \")\n",
|
||||
" display(ipd.Audio(wav, rate=24000, normalize=False))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9320da63",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Long-form generation\n",
|
||||
"This section includes basic implementation of Algorithm 1 in the paper for consistent longform audio generation. The example passage is taken from [Section 5](https://styletts2.github.io/#long) of the demo page. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cdd4db51",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"passage = '''If the supply of fruit is greater than the family needs, it may be made a source of income by sending the fresh fruit to the market if there is one near enough, or by preserving, canning, and making jelly for sale. To make such an enterprise a success the fruit and work must be first class. There is magic in the word \"Homemade,\" when the product appeals to the eye and the palate; but many careless and incompetent people have found to their sorrow that this word has not magic enough to float inferior goods on the market. As a rule large canning and preserving establishments are clean and have the best appliances, and they employ chemists and skilled labor. The home product must be very good to compete with the attractive goods that are sent out from such establishments. Yet for first-class homemade products there is a market in all large cities. All first-class grocers have customers who purchase such goods.'''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ebb941c8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def LFinference(text, s_prev, noise, alpha=0.7, diffusion_steps=5, embedding_scale=1):\n",
|
||||
" text = text.strip()\n",
|
||||
" text = text.replace('\"', '')\n",
|
||||
" ps = global_phonemizer.phonemize([text])\n",
|
||||
" ps = word_tokenize(ps[0])\n",
|
||||
" ps = ' '.join(ps)\n",
|
||||
"\n",
|
||||
" tokens = textclenaer(ps)\n",
|
||||
" tokens.insert(0, 0)\n",
|
||||
" tokens = torch.LongTensor(tokens).to(device).unsqueeze(0)\n",
|
||||
" \n",
|
||||
" with torch.no_grad():\n",
|
||||
" input_lengths = torch.LongTensor([tokens.shape[-1]]).to(tokens.device)\n",
|
||||
" text_mask = length_to_mask(input_lengths).to(tokens.device)\n",
|
||||
"\n",
|
||||
" t_en = model.text_encoder(tokens, input_lengths, text_mask)\n",
|
||||
" bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())\n",
|
||||
" d_en = model.bert_encoder(bert_dur).transpose(-1, -2) \n",
|
||||
"\n",
|
||||
" s_pred = sampler(noise, \n",
|
||||
" embedding=bert_dur[0].unsqueeze(0), num_steps=diffusion_steps,\n",
|
||||
" embedding_scale=embedding_scale).squeeze(0)\n",
|
||||
" \n",
|
||||
" if s_prev is not None:\n",
|
||||
" # convex combination of previous and current style\n",
|
||||
" s_pred = alpha * s_prev + (1 - alpha) * s_pred\n",
|
||||
" \n",
|
||||
" s = s_pred[:, 128:]\n",
|
||||
" ref = s_pred[:, :128]\n",
|
||||
"\n",
|
||||
" d = model.predictor.text_encoder(d_en, s, input_lengths, text_mask)\n",
|
||||
"\n",
|
||||
" x, _ = model.predictor.lstm(d)\n",
|
||||
" duration = model.predictor.duration_proj(x)\n",
|
||||
" duration = torch.sigmoid(duration).sum(axis=-1)\n",
|
||||
" pred_dur = torch.round(duration.squeeze()).clamp(min=1)\n",
|
||||
"\n",
|
||||
" pred_aln_trg = torch.zeros(input_lengths, int(pred_dur.sum().data))\n",
|
||||
" c_frame = 0\n",
|
||||
" for i in range(pred_aln_trg.size(0)):\n",
|
||||
" pred_aln_trg[i, c_frame:c_frame + int(pred_dur[i].data)] = 1\n",
|
||||
" c_frame += int(pred_dur[i].data)\n",
|
||||
"\n",
|
||||
" # encode prosody\n",
|
||||
" en = (d.transpose(-1, -2) @ pred_aln_trg.unsqueeze(0).to(device))\n",
|
||||
" F0_pred, N_pred = model.predictor.F0Ntrain(en, s)\n",
|
||||
" out = model.decoder((t_en @ pred_aln_trg.unsqueeze(0).to(device)), \n",
|
||||
" F0_pred, N_pred, ref.squeeze().unsqueeze(0))\n",
|
||||
" \n",
|
||||
" return out.squeeze().cpu().numpy(), s_pred"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7ca0ef2e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"sentences = passage.split('.') # simple split by comma\n",
|
||||
"wavs = []\n",
|
||||
"s_prev = None\n",
|
||||
"for text in sentences:\n",
|
||||
" if text.strip() == \"\": continue\n",
|
||||
" text += '.' # add it back\n",
|
||||
" noise = torch.randn(1,1,256).to(device)\n",
|
||||
" wav, s_prev = LFinference(text, s_prev, noise, alpha=0.7, diffusion_steps=10, embedding_scale=1.5)\n",
|
||||
" wavs.append(wav)\n",
|
||||
"display(ipd.Audio(np.concatenate(wavs), rate=24000, normalize=False))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "NLP",
|
||||
"language": "python",
|
||||
"name": "nlp"
|
||||
},
|
||||
"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.9.7"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Aaron (Yinghao) Li
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,110 @@
|
||||
log_dir: "Models/LJSpeech"
|
||||
save_freq: 5
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs: 50 # number of finetuning epoch (1 hour of data)
|
||||
batch_size: 8
|
||||
max_len: 400 # maximum number of frames
|
||||
pretrained_model: "Models/LibriTTS/epochs_2nd_00020.pth"
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: true # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_harness.txt"
|
||||
val_data: "Data/val_harness.txt"
|
||||
root_path: ""
|
||||
OOD_data: "Data/OOD_harness.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: true
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'hifigan' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10,5,3,2]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20,10,6,4]
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (TMA)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss
|
||||
lambda_norm: 1. # norm reconstruction loss
|
||||
lambda_dur: 1. # duration loss
|
||||
lambda_ce: 20. # duration predictor probability output CE loss
|
||||
lambda_sty: 1. # style reconstruction loss
|
||||
lambda_diff: 1. # score matching loss
|
||||
|
||||
diff_epoch: 10 # style diffusion starting epoch
|
||||
joint_epoch: 30 # joint training starting epoch
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.0001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 10 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
@@ -0,0 +1 @@
|
||||
epochs_2nd_00020.pth filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -0,0 +1,21 @@
|
||||
{ASR_config: Utils/ASR/config.yml, ASR_path: Utils/ASR/epoch_00080.pth, F0_path: Utils/JDC/bst.t7,
|
||||
PLBERT_dir: Utils/PLBERT/, batch_size: 8, data_params: {OOD_data: Data/OOD_texts.txt,
|
||||
min_length: 50, root_path: '', train_data: Data/train_list.txt, val_data: Data/val_list.txt},
|
||||
device: cuda, epochs_1st: 40, epochs_2nd: 25, first_stage_path: first_stage.pth,
|
||||
load_only_params: false, log_dir: Models/LibriTTS, log_interval: 10, loss_params: {
|
||||
TMA_epoch: 4, diff_epoch: 0, joint_epoch: 0, lambda_F0: 1.0, lambda_ce: 20.0,
|
||||
lambda_diff: 1.0, lambda_dur: 1.0, lambda_gen: 1.0, lambda_mel: 5.0, lambda_mono: 1.0,
|
||||
lambda_norm: 1.0, lambda_s2s: 1.0, lambda_slm: 1.0, lambda_sty: 1.0}, max_len: 300,
|
||||
model_params: {decoder: {resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3,
|
||||
5]], resblock_kernel_sizes: [3, 7, 11], type: hifigan, upsample_initial_channel: 512,
|
||||
upsample_kernel_sizes: [20, 10, 6, 4], upsample_rates: [10, 5, 3, 2]}, diffusion: {
|
||||
dist: {estimate_sigma_data: true, mean: -3.0, sigma_data: 0.19926648961191362,
|
||||
std: 1.0}, embedding_mask_proba: 0.1, transformer: {head_features: 64, multiplier: 2,
|
||||
num_heads: 8, num_layers: 3}}, dim_in: 64, dropout: 0.2, hidden_dim: 512,
|
||||
max_conv_dim: 512, max_dur: 50, multispeaker: true, n_layer: 3, n_mels: 80, n_token: 178,
|
||||
slm: {hidden: 768, initial_channel: 64, model: microsoft/wavlm-base-plus, nlayers: 13,
|
||||
sr: 16000}, style_dim: 128}, optimizer_params: {bert_lr: 1.0e-05, ft_lr: 1.0e-05,
|
||||
lr: 0.0001}, preprocess_params: {spect_params: {hop_length: 300, n_fft: 2048,
|
||||
win_length: 1200}, sr: 24000}, pretrained_model: Models/LibriTTS/epoch_2nd_00002.pth,
|
||||
save_freq: 1, second_stage_load_pretrained: true, slmadv_params: {batch_percentage: 0.5,
|
||||
iter: 20, max_len: 500, min_len: 400, scale: 0.01, sig: 1.5, thresh: 5}}
|
||||
@@ -0,0 +1,111 @@
|
||||
log_dir: "Models/LJSpeech"
|
||||
save_freq: 5
|
||||
log_interval: 10
|
||||
device: "cuda"
|
||||
epochs: 50 # number of finetuning epoch (1 hour of data)
|
||||
batch_size: 1
|
||||
max_len: 400 # maximum number of frames
|
||||
pretrained_model: "Models/LibriTTS/epochs_2nd_00020.pth"
|
||||
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
||||
load_only_params: true # set to true if do not want to load epoch numbers and optimizer parameters
|
||||
|
||||
F0_path: "Utils/JDC/bst.t7"
|
||||
ASR_config: "Utils/ASR/config.yml"
|
||||
ASR_path: "Utils/ASR/epoch_00080.pth"
|
||||
PLBERT_dir: 'Utils/PLBERT/'
|
||||
|
||||
data_params:
|
||||
train_data: "Data/train_harness.txt"
|
||||
val_data: "Data/val_harness.txt"
|
||||
root_path: ""
|
||||
OOD_data: "Data/OOD_harness.txt"
|
||||
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
||||
|
||||
preprocess_params:
|
||||
sr: 24000
|
||||
spect_params:
|
||||
n_fft: 2048
|
||||
win_length: 1200
|
||||
hop_length: 300
|
||||
|
||||
model_params:
|
||||
multispeaker: true
|
||||
|
||||
dim_in: 64
|
||||
hidden_dim: 512
|
||||
max_conv_dim: 512
|
||||
n_layer: 3
|
||||
n_mels: 80
|
||||
|
||||
n_token: 178 # number of phoneme tokens
|
||||
max_dur: 50 # maximum duration of a single phoneme
|
||||
style_dim: 128 # style vector size
|
||||
|
||||
dropout: 0.2
|
||||
|
||||
# config for decoder
|
||||
decoder:
|
||||
type: 'hifigan' # either hifigan or istftnet
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
upsample_rates : [10,5,3,2]
|
||||
upsample_initial_channel: 512
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
upsample_kernel_sizes: [20,10,6,4]
|
||||
|
||||
# speech language model config
|
||||
slm:
|
||||
model: 'microsoft/wavlm-base-plus'
|
||||
sr: 16000 # sampling rate of SLM
|
||||
hidden: 768 # hidden size of SLM
|
||||
nlayers: 13 # number of layers of SLM
|
||||
initial_channel: 64 # initial channels of SLM discriminator head
|
||||
|
||||
# style diffusion model config
|
||||
diffusion:
|
||||
embedding_mask_proba: 0.1
|
||||
# transformer config
|
||||
transformer:
|
||||
num_layers: 3
|
||||
num_heads: 8
|
||||
head_features: 64
|
||||
multiplier: 2
|
||||
|
||||
# diffusion distribution config
|
||||
dist:
|
||||
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
||||
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
||||
mean: -3.0
|
||||
std: 1.0
|
||||
|
||||
loss_params:
|
||||
lambda_mel: 5. # mel reconstruction loss
|
||||
lambda_gen: 1. # generator loss
|
||||
lambda_slm: 1. # slm feature matching loss
|
||||
|
||||
lambda_mono: 1. # monotonic alignment loss (TMA)
|
||||
lambda_s2s: 1. # sequence-to-sequence loss (TMA)
|
||||
|
||||
lambda_F0: 1. # F0 reconstruction loss
|
||||
lambda_norm: 1. # norm reconstruction loss
|
||||
lambda_dur: 1. # duration loss
|
||||
lambda_ce: 20. # duration predictor probability output CE loss
|
||||
lambda_sty: 1. # style reconstruction loss
|
||||
lambda_diff: 1. # score matching loss
|
||||
|
||||
diff_epoch: 10 # style diffusion starting epoch
|
||||
joint_epoch: 30 # joint training starting epoch
|
||||
|
||||
optimizer_params:
|
||||
lr: 0.0001 # general learning rate
|
||||
bert_lr: 0.00001 # learning rate for PLBERT
|
||||
ft_lr: 0.0001 # learning rate for acoustic modules
|
||||
|
||||
slmadv_params:
|
||||
min_len: 400 # minimum length of samples
|
||||
max_len: 500 # maximum length of samples
|
||||
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
||||
iter: 10 # update the discriminator every this iterations of generator update
|
||||
thresh: 5 # gradient norm above which the gradient is scaled
|
||||
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
||||
sig: 1.5 # sigma for differentiable duration modeling
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
from math import pi
|
||||
from random import randint
|
||||
from typing import Any, Optional, Sequence, Tuple, Union
|
||||
|
||||
import torch
|
||||
from einops import rearrange
|
||||
from torch import Tensor, nn
|
||||
from tqdm import tqdm
|
||||
|
||||
from .utils import *
|
||||
from .sampler import *
|
||||
|
||||
"""
|
||||
Diffusion Classes (generic for 1d data)
|
||||
"""
|
||||
|
||||
|
||||
class Model1d(nn.Module):
|
||||
def __init__(self, unet_type: str = "base", **kwargs):
|
||||
super().__init__()
|
||||
diffusion_kwargs, kwargs = groupby("diffusion_", kwargs)
|
||||
self.unet = None
|
||||
self.diffusion = None
|
||||
|
||||
def forward(self, x: Tensor, **kwargs) -> Tensor:
|
||||
return self.diffusion(x, **kwargs)
|
||||
|
||||
def sample(self, *args, **kwargs) -> Tensor:
|
||||
return self.diffusion.sample(*args, **kwargs)
|
||||
|
||||
|
||||
"""
|
||||
Audio Diffusion Classes (specific for 1d audio data)
|
||||
"""
|
||||
|
||||
|
||||
def get_default_model_kwargs():
|
||||
return dict(
|
||||
channels=128,
|
||||
patch_size=16,
|
||||
multipliers=[1, 2, 4, 4, 4, 4, 4],
|
||||
factors=[4, 4, 4, 2, 2, 2],
|
||||
num_blocks=[2, 2, 2, 2, 2, 2],
|
||||
attentions=[0, 0, 0, 1, 1, 1, 1],
|
||||
attention_heads=8,
|
||||
attention_features=64,
|
||||
attention_multiplier=2,
|
||||
attention_use_rel_pos=False,
|
||||
diffusion_type="v",
|
||||
diffusion_sigma_distribution=UniformDistribution(),
|
||||
)
|
||||
|
||||
|
||||
def get_default_sampling_kwargs():
|
||||
return dict(sigma_schedule=LinearSchedule(), sampler=VSampler(), clamp=True)
|
||||
|
||||
|
||||
class AudioDiffusionModel(Model1d):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**{**get_default_model_kwargs(), **kwargs})
|
||||
|
||||
def sample(self, *args, **kwargs):
|
||||
return super().sample(*args, **{**get_default_sampling_kwargs(), **kwargs})
|
||||
|
||||
|
||||
class AudioDiffusionConditional(Model1d):
|
||||
def __init__(
|
||||
self,
|
||||
embedding_features: int,
|
||||
embedding_max_length: int,
|
||||
embedding_mask_proba: float = 0.1,
|
||||
**kwargs,
|
||||
):
|
||||
self.embedding_mask_proba = embedding_mask_proba
|
||||
default_kwargs = dict(
|
||||
**get_default_model_kwargs(),
|
||||
unet_type="cfg",
|
||||
context_embedding_features=embedding_features,
|
||||
context_embedding_max_length=embedding_max_length,
|
||||
)
|
||||
super().__init__(**{**default_kwargs, **kwargs})
|
||||
|
||||
def forward(self, *args, **kwargs):
|
||||
default_kwargs = dict(embedding_mask_proba=self.embedding_mask_proba)
|
||||
return super().forward(*args, **{**default_kwargs, **kwargs})
|
||||
|
||||
def sample(self, *args, **kwargs):
|
||||
default_kwargs = dict(
|
||||
**get_default_sampling_kwargs(),
|
||||
embedding_scale=5.0,
|
||||
)
|
||||
return super().sample(*args, **{**default_kwargs, **kwargs})
|
||||
|
||||
|
||||
@@ -0,0 +1,693 @@
|
||||
from math import floor, log, pi
|
||||
from typing import Any, List, Optional, Sequence, Tuple, Union
|
||||
|
||||
from .utils import *
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from einops import rearrange, reduce, repeat
|
||||
from einops.layers.torch import Rearrange
|
||||
from einops_exts import rearrange_many
|
||||
from torch import Tensor, einsum
|
||||
|
||||
|
||||
"""
|
||||
Utils
|
||||
"""
|
||||
|
||||
class AdaLayerNorm(nn.Module):
|
||||
def __init__(self, style_dim, channels, eps=1e-5):
|
||||
super().__init__()
|
||||
self.channels = channels
|
||||
self.eps = eps
|
||||
|
||||
self.fc = nn.Linear(style_dim, channels*2)
|
||||
|
||||
def forward(self, x, s):
|
||||
x = x.transpose(-1, -2)
|
||||
x = x.transpose(1, -1)
|
||||
|
||||
h = self.fc(s)
|
||||
h = h.view(h.size(0), h.size(1), 1)
|
||||
gamma, beta = torch.chunk(h, chunks=2, dim=1)
|
||||
gamma, beta = gamma.transpose(1, -1), beta.transpose(1, -1)
|
||||
|
||||
|
||||
x = F.layer_norm(x, (self.channels,), eps=self.eps)
|
||||
x = (1 + gamma) * x + beta
|
||||
return x.transpose(1, -1).transpose(-1, -2)
|
||||
|
||||
class StyleTransformer1d(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
num_layers: int,
|
||||
channels: int,
|
||||
num_heads: int,
|
||||
head_features: int,
|
||||
multiplier: int,
|
||||
use_context_time: bool = True,
|
||||
use_rel_pos: bool = False,
|
||||
context_features_multiplier: int = 1,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
context_features: Optional[int] = None,
|
||||
context_embedding_features: Optional[int] = None,
|
||||
embedding_max_length: int = 512,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.blocks = nn.ModuleList(
|
||||
[
|
||||
StyleTransformerBlock(
|
||||
features=channels + context_embedding_features,
|
||||
head_features=head_features,
|
||||
num_heads=num_heads,
|
||||
multiplier=multiplier,
|
||||
style_dim=context_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
for i in range(num_layers)
|
||||
]
|
||||
)
|
||||
|
||||
self.to_out = nn.Sequential(
|
||||
Rearrange("b t c -> b c t"),
|
||||
nn.Conv1d(
|
||||
in_channels=channels + context_embedding_features,
|
||||
out_channels=channels,
|
||||
kernel_size=1,
|
||||
),
|
||||
)
|
||||
|
||||
use_context_features = exists(context_features)
|
||||
self.use_context_features = use_context_features
|
||||
self.use_context_time = use_context_time
|
||||
|
||||
if use_context_time or use_context_features:
|
||||
context_mapping_features = channels + context_embedding_features
|
||||
|
||||
self.to_mapping = nn.Sequential(
|
||||
nn.Linear(context_mapping_features, context_mapping_features),
|
||||
nn.GELU(),
|
||||
nn.Linear(context_mapping_features, context_mapping_features),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
if use_context_time:
|
||||
assert exists(context_mapping_features)
|
||||
self.to_time = nn.Sequential(
|
||||
TimePositionalEmbedding(
|
||||
dim=channels, out_features=context_mapping_features
|
||||
),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
if use_context_features:
|
||||
assert exists(context_features) and exists(context_mapping_features)
|
||||
self.to_features = nn.Sequential(
|
||||
nn.Linear(
|
||||
in_features=context_features, out_features=context_mapping_features
|
||||
),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
self.fixed_embedding = FixedEmbedding(
|
||||
max_length=embedding_max_length, features=context_embedding_features
|
||||
)
|
||||
|
||||
|
||||
def get_mapping(
|
||||
self, time: Optional[Tensor] = None, features: Optional[Tensor] = None
|
||||
) -> Optional[Tensor]:
|
||||
"""Combines context time features and features into mapping"""
|
||||
items, mapping = [], None
|
||||
# Compute time features
|
||||
if self.use_context_time:
|
||||
assert_message = "use_context_time=True but no time features provided"
|
||||
assert exists(time), assert_message
|
||||
items += [self.to_time(time)]
|
||||
# Compute features
|
||||
if self.use_context_features:
|
||||
assert_message = "context_features exists but no features provided"
|
||||
assert exists(features), assert_message
|
||||
items += [self.to_features(features)]
|
||||
|
||||
# Compute joint mapping
|
||||
if self.use_context_time or self.use_context_features:
|
||||
mapping = reduce(torch.stack(items), "n b m -> b m", "sum")
|
||||
mapping = self.to_mapping(mapping)
|
||||
|
||||
return mapping
|
||||
|
||||
def run(self, x, time, embedding, features):
|
||||
|
||||
mapping = self.get_mapping(time, features)
|
||||
x = torch.cat([x.expand(-1, embedding.size(1), -1), embedding], axis=-1)
|
||||
mapping = mapping.unsqueeze(1).expand(-1, embedding.size(1), -1)
|
||||
|
||||
for block in self.blocks:
|
||||
x = x + mapping
|
||||
x = block(x, features)
|
||||
|
||||
x = x.mean(axis=1).unsqueeze(1)
|
||||
x = self.to_out(x)
|
||||
x = x.transpose(-1, -2)
|
||||
|
||||
return x
|
||||
|
||||
def forward(self, x: Tensor,
|
||||
time: Tensor,
|
||||
embedding_mask_proba: float = 0.0,
|
||||
embedding: Optional[Tensor] = None,
|
||||
features: Optional[Tensor] = None,
|
||||
embedding_scale: float = 1.0) -> Tensor:
|
||||
|
||||
b, device = embedding.shape[0], embedding.device
|
||||
fixed_embedding = self.fixed_embedding(embedding)
|
||||
if embedding_mask_proba > 0.0:
|
||||
# Randomly mask embedding
|
||||
batch_mask = rand_bool(
|
||||
shape=(b, 1, 1), proba=embedding_mask_proba, device=device
|
||||
)
|
||||
embedding = torch.where(batch_mask, fixed_embedding, embedding)
|
||||
|
||||
if embedding_scale != 1.0:
|
||||
# Compute both normal and fixed embedding outputs
|
||||
out = self.run(x, time, embedding=embedding, features=features)
|
||||
out_masked = self.run(x, time, embedding=fixed_embedding, features=features)
|
||||
# Scale conditional output using classifier-free guidance
|
||||
return out_masked + (out - out_masked) * embedding_scale
|
||||
else:
|
||||
return self.run(x, time, embedding=embedding, features=features)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
class StyleTransformerBlock(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
features: int,
|
||||
num_heads: int,
|
||||
head_features: int,
|
||||
style_dim: int,
|
||||
multiplier: int,
|
||||
use_rel_pos: bool,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
context_features: Optional[int] = None,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.use_cross_attention = exists(context_features) and context_features > 0
|
||||
|
||||
self.attention = StyleAttention(
|
||||
features=features,
|
||||
style_dim=style_dim,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
if self.use_cross_attention:
|
||||
self.cross_attention = StyleAttention(
|
||||
features=features,
|
||||
style_dim=style_dim,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
context_features=context_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
self.feed_forward = FeedForward(features=features, multiplier=multiplier)
|
||||
|
||||
def forward(self, x: Tensor, s: Tensor, *, context: Optional[Tensor] = None) -> Tensor:
|
||||
x = self.attention(x, s) + x
|
||||
if self.use_cross_attention:
|
||||
x = self.cross_attention(x, s, context=context) + x
|
||||
x = self.feed_forward(x) + x
|
||||
return x
|
||||
|
||||
class StyleAttention(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
features: int,
|
||||
*,
|
||||
style_dim: int,
|
||||
head_features: int,
|
||||
num_heads: int,
|
||||
context_features: Optional[int] = None,
|
||||
use_rel_pos: bool,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
):
|
||||
super().__init__()
|
||||
self.context_features = context_features
|
||||
mid_features = head_features * num_heads
|
||||
context_features = default(context_features, features)
|
||||
|
||||
self.norm = AdaLayerNorm(style_dim, features)
|
||||
self.norm_context = AdaLayerNorm(style_dim, context_features)
|
||||
self.to_q = nn.Linear(
|
||||
in_features=features, out_features=mid_features, bias=False
|
||||
)
|
||||
self.to_kv = nn.Linear(
|
||||
in_features=context_features, out_features=mid_features * 2, bias=False
|
||||
)
|
||||
self.attention = AttentionBase(
|
||||
features,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
def forward(self, x: Tensor, s: Tensor, *, context: Optional[Tensor] = None) -> Tensor:
|
||||
assert_message = "You must provide a context when using context_features"
|
||||
assert not self.context_features or exists(context), assert_message
|
||||
# Use context if provided
|
||||
context = default(context, x)
|
||||
# Normalize then compute q from input and k,v from context
|
||||
x, context = self.norm(x, s), self.norm_context(context, s)
|
||||
|
||||
q, k, v = (self.to_q(x), *torch.chunk(self.to_kv(context), chunks=2, dim=-1))
|
||||
# Compute and return attention
|
||||
return self.attention(q, k, v)
|
||||
|
||||
class Transformer1d(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
num_layers: int,
|
||||
channels: int,
|
||||
num_heads: int,
|
||||
head_features: int,
|
||||
multiplier: int,
|
||||
use_context_time: bool = True,
|
||||
use_rel_pos: bool = False,
|
||||
context_features_multiplier: int = 1,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
context_features: Optional[int] = None,
|
||||
context_embedding_features: Optional[int] = None,
|
||||
embedding_max_length: int = 512,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.blocks = nn.ModuleList(
|
||||
[
|
||||
TransformerBlock(
|
||||
features=channels + context_embedding_features,
|
||||
head_features=head_features,
|
||||
num_heads=num_heads,
|
||||
multiplier=multiplier,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
for i in range(num_layers)
|
||||
]
|
||||
)
|
||||
|
||||
self.to_out = nn.Sequential(
|
||||
Rearrange("b t c -> b c t"),
|
||||
nn.Conv1d(
|
||||
in_channels=channels + context_embedding_features,
|
||||
out_channels=channels,
|
||||
kernel_size=1,
|
||||
),
|
||||
)
|
||||
|
||||
use_context_features = exists(context_features)
|
||||
self.use_context_features = use_context_features
|
||||
self.use_context_time = use_context_time
|
||||
|
||||
if use_context_time or use_context_features:
|
||||
context_mapping_features = channels + context_embedding_features
|
||||
|
||||
self.to_mapping = nn.Sequential(
|
||||
nn.Linear(context_mapping_features, context_mapping_features),
|
||||
nn.GELU(),
|
||||
nn.Linear(context_mapping_features, context_mapping_features),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
if use_context_time:
|
||||
assert exists(context_mapping_features)
|
||||
self.to_time = nn.Sequential(
|
||||
TimePositionalEmbedding(
|
||||
dim=channels, out_features=context_mapping_features
|
||||
),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
if use_context_features:
|
||||
assert exists(context_features) and exists(context_mapping_features)
|
||||
self.to_features = nn.Sequential(
|
||||
nn.Linear(
|
||||
in_features=context_features, out_features=context_mapping_features
|
||||
),
|
||||
nn.GELU(),
|
||||
)
|
||||
|
||||
self.fixed_embedding = FixedEmbedding(
|
||||
max_length=embedding_max_length, features=context_embedding_features
|
||||
)
|
||||
|
||||
|
||||
def get_mapping(
|
||||
self, time: Optional[Tensor] = None, features: Optional[Tensor] = None
|
||||
) -> Optional[Tensor]:
|
||||
"""Combines context time features and features into mapping"""
|
||||
items, mapping = [], None
|
||||
# Compute time features
|
||||
if self.use_context_time:
|
||||
assert_message = "use_context_time=True but no time features provided"
|
||||
assert exists(time), assert_message
|
||||
items += [self.to_time(time)]
|
||||
# Compute features
|
||||
if self.use_context_features:
|
||||
assert_message = "context_features exists but no features provided"
|
||||
assert exists(features), assert_message
|
||||
items += [self.to_features(features)]
|
||||
|
||||
# Compute joint mapping
|
||||
if self.use_context_time or self.use_context_features:
|
||||
mapping = reduce(torch.stack(items), "n b m -> b m", "sum")
|
||||
mapping = self.to_mapping(mapping)
|
||||
|
||||
return mapping
|
||||
|
||||
def run(self, x, time, embedding, features):
|
||||
|
||||
mapping = self.get_mapping(time, features)
|
||||
x = torch.cat([x.expand(-1, embedding.size(1), -1), embedding], axis=-1)
|
||||
mapping = mapping.unsqueeze(1).expand(-1, embedding.size(1), -1)
|
||||
|
||||
for block in self.blocks:
|
||||
x = x + mapping
|
||||
x = block(x)
|
||||
|
||||
x = x.mean(axis=1).unsqueeze(1)
|
||||
x = self.to_out(x)
|
||||
x = x.transpose(-1, -2)
|
||||
|
||||
return x
|
||||
|
||||
def forward(self, x: Tensor,
|
||||
time: Tensor,
|
||||
embedding_mask_proba: float = 0.0,
|
||||
embedding: Optional[Tensor] = None,
|
||||
features: Optional[Tensor] = None,
|
||||
embedding_scale: float = 1.0) -> Tensor:
|
||||
|
||||
b, device = embedding.shape[0], embedding.device
|
||||
fixed_embedding = self.fixed_embedding(embedding)
|
||||
if embedding_mask_proba > 0.0:
|
||||
# Randomly mask embedding
|
||||
batch_mask = rand_bool(
|
||||
shape=(b, 1, 1), proba=embedding_mask_proba, device=device
|
||||
)
|
||||
embedding = torch.where(batch_mask, fixed_embedding, embedding)
|
||||
|
||||
if embedding_scale != 1.0:
|
||||
# Compute both normal and fixed embedding outputs
|
||||
out = self.run(x, time, embedding=embedding, features=features)
|
||||
out_masked = self.run(x, time, embedding=fixed_embedding, features=features)
|
||||
# Scale conditional output using classifier-free guidance
|
||||
return out_masked + (out - out_masked) * embedding_scale
|
||||
else:
|
||||
return self.run(x, time, embedding=embedding, features=features)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
"""
|
||||
Attention Components
|
||||
"""
|
||||
|
||||
|
||||
class RelativePositionBias(nn.Module):
|
||||
def __init__(self, num_buckets: int, max_distance: int, num_heads: int):
|
||||
super().__init__()
|
||||
self.num_buckets = num_buckets
|
||||
self.max_distance = max_distance
|
||||
self.num_heads = num_heads
|
||||
self.relative_attention_bias = nn.Embedding(num_buckets, num_heads)
|
||||
|
||||
@staticmethod
|
||||
def _relative_position_bucket(
|
||||
relative_position: Tensor, num_buckets: int, max_distance: int
|
||||
):
|
||||
num_buckets //= 2
|
||||
ret = (relative_position >= 0).to(torch.long) * num_buckets
|
||||
n = torch.abs(relative_position)
|
||||
|
||||
max_exact = num_buckets // 2
|
||||
is_small = n < max_exact
|
||||
|
||||
val_if_large = (
|
||||
max_exact
|
||||
+ (
|
||||
torch.log(n.float() / max_exact)
|
||||
/ log(max_distance / max_exact)
|
||||
* (num_buckets - max_exact)
|
||||
).long()
|
||||
)
|
||||
val_if_large = torch.min(
|
||||
val_if_large, torch.full_like(val_if_large, num_buckets - 1)
|
||||
)
|
||||
|
||||
ret += torch.where(is_small, n, val_if_large)
|
||||
return ret
|
||||
|
||||
def forward(self, num_queries: int, num_keys: int) -> Tensor:
|
||||
i, j, device = num_queries, num_keys, self.relative_attention_bias.weight.device
|
||||
q_pos = torch.arange(j - i, j, dtype=torch.long, device=device)
|
||||
k_pos = torch.arange(j, dtype=torch.long, device=device)
|
||||
rel_pos = rearrange(k_pos, "j -> 1 j") - rearrange(q_pos, "i -> i 1")
|
||||
|
||||
relative_position_bucket = self._relative_position_bucket(
|
||||
rel_pos, num_buckets=self.num_buckets, max_distance=self.max_distance
|
||||
)
|
||||
|
||||
bias = self.relative_attention_bias(relative_position_bucket)
|
||||
bias = rearrange(bias, "m n h -> 1 h m n")
|
||||
return bias
|
||||
|
||||
|
||||
def FeedForward(features: int, multiplier: int) -> nn.Module:
|
||||
mid_features = features * multiplier
|
||||
return nn.Sequential(
|
||||
nn.Linear(in_features=features, out_features=mid_features),
|
||||
nn.GELU(),
|
||||
nn.Linear(in_features=mid_features, out_features=features),
|
||||
)
|
||||
|
||||
|
||||
class AttentionBase(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
features: int,
|
||||
*,
|
||||
head_features: int,
|
||||
num_heads: int,
|
||||
use_rel_pos: bool,
|
||||
out_features: Optional[int] = None,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
):
|
||||
super().__init__()
|
||||
self.scale = head_features ** -0.5
|
||||
self.num_heads = num_heads
|
||||
self.use_rel_pos = use_rel_pos
|
||||
mid_features = head_features * num_heads
|
||||
|
||||
if use_rel_pos:
|
||||
assert exists(rel_pos_num_buckets) and exists(rel_pos_max_distance)
|
||||
self.rel_pos = RelativePositionBias(
|
||||
num_buckets=rel_pos_num_buckets,
|
||||
max_distance=rel_pos_max_distance,
|
||||
num_heads=num_heads,
|
||||
)
|
||||
if out_features is None:
|
||||
out_features = features
|
||||
|
||||
self.to_out = nn.Linear(in_features=mid_features, out_features=out_features)
|
||||
|
||||
def forward(self, q: Tensor, k: Tensor, v: Tensor) -> Tensor:
|
||||
# Split heads
|
||||
q, k, v = rearrange_many((q, k, v), "b n (h d) -> b h n d", h=self.num_heads)
|
||||
# Compute similarity matrix
|
||||
sim = einsum("... n d, ... m d -> ... n m", q, k)
|
||||
sim = (sim + self.rel_pos(*sim.shape[-2:])) if self.use_rel_pos else sim
|
||||
sim = sim * self.scale
|
||||
# Get attention matrix with softmax
|
||||
attn = sim.softmax(dim=-1)
|
||||
# Compute values
|
||||
out = einsum("... n m, ... m d -> ... n d", attn, v)
|
||||
out = rearrange(out, "b h n d -> b n (h d)")
|
||||
return self.to_out(out)
|
||||
|
||||
|
||||
class Attention(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
features: int,
|
||||
*,
|
||||
head_features: int,
|
||||
num_heads: int,
|
||||
out_features: Optional[int] = None,
|
||||
context_features: Optional[int] = None,
|
||||
use_rel_pos: bool,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
):
|
||||
super().__init__()
|
||||
self.context_features = context_features
|
||||
mid_features = head_features * num_heads
|
||||
context_features = default(context_features, features)
|
||||
|
||||
self.norm = nn.LayerNorm(features)
|
||||
self.norm_context = nn.LayerNorm(context_features)
|
||||
self.to_q = nn.Linear(
|
||||
in_features=features, out_features=mid_features, bias=False
|
||||
)
|
||||
self.to_kv = nn.Linear(
|
||||
in_features=context_features, out_features=mid_features * 2, bias=False
|
||||
)
|
||||
|
||||
self.attention = AttentionBase(
|
||||
features,
|
||||
out_features=out_features,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
def forward(self, x: Tensor, *, context: Optional[Tensor] = None) -> Tensor:
|
||||
assert_message = "You must provide a context when using context_features"
|
||||
assert not self.context_features or exists(context), assert_message
|
||||
# Use context if provided
|
||||
context = default(context, x)
|
||||
# Normalize then compute q from input and k,v from context
|
||||
x, context = self.norm(x), self.norm_context(context)
|
||||
q, k, v = (self.to_q(x), *torch.chunk(self.to_kv(context), chunks=2, dim=-1))
|
||||
# Compute and return attention
|
||||
return self.attention(q, k, v)
|
||||
|
||||
|
||||
"""
|
||||
Transformer Blocks
|
||||
"""
|
||||
|
||||
|
||||
class TransformerBlock(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
features: int,
|
||||
num_heads: int,
|
||||
head_features: int,
|
||||
multiplier: int,
|
||||
use_rel_pos: bool,
|
||||
rel_pos_num_buckets: Optional[int] = None,
|
||||
rel_pos_max_distance: Optional[int] = None,
|
||||
context_features: Optional[int] = None,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.use_cross_attention = exists(context_features) and context_features > 0
|
||||
|
||||
self.attention = Attention(
|
||||
features=features,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
if self.use_cross_attention:
|
||||
self.cross_attention = Attention(
|
||||
features=features,
|
||||
num_heads=num_heads,
|
||||
head_features=head_features,
|
||||
context_features=context_features,
|
||||
use_rel_pos=use_rel_pos,
|
||||
rel_pos_num_buckets=rel_pos_num_buckets,
|
||||
rel_pos_max_distance=rel_pos_max_distance,
|
||||
)
|
||||
|
||||
self.feed_forward = FeedForward(features=features, multiplier=multiplier)
|
||||
|
||||
def forward(self, x: Tensor, *, context: Optional[Tensor] = None) -> Tensor:
|
||||
x = self.attention(x) + x
|
||||
if self.use_cross_attention:
|
||||
x = self.cross_attention(x, context=context) + x
|
||||
x = self.feed_forward(x) + x
|
||||
return x
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Time Embeddings
|
||||
"""
|
||||
|
||||
|
||||
class SinusoidalEmbedding(nn.Module):
|
||||
def __init__(self, dim: int):
|
||||
super().__init__()
|
||||
self.dim = dim
|
||||
|
||||
def forward(self, x: Tensor) -> Tensor:
|
||||
device, half_dim = x.device, self.dim // 2
|
||||
emb = torch.tensor(log(10000) / (half_dim - 1), device=device)
|
||||
emb = torch.exp(torch.arange(half_dim, device=device) * -emb)
|
||||
emb = rearrange(x, "i -> i 1") * rearrange(emb, "j -> 1 j")
|
||||
return torch.cat((emb.sin(), emb.cos()), dim=-1)
|
||||
|
||||
|
||||
class LearnedPositionalEmbedding(nn.Module):
|
||||
"""Used for continuous time"""
|
||||
|
||||
def __init__(self, dim: int):
|
||||
super().__init__()
|
||||
assert (dim % 2) == 0
|
||||
half_dim = dim // 2
|
||||
self.weights = nn.Parameter(torch.randn(half_dim))
|
||||
|
||||
def forward(self, x: Tensor) -> Tensor:
|
||||
x = rearrange(x, "b -> b 1")
|
||||
freqs = x * rearrange(self.weights, "d -> 1 d") * 2 * pi
|
||||
fouriered = torch.cat((freqs.sin(), freqs.cos()), dim=-1)
|
||||
fouriered = torch.cat((x, fouriered), dim=-1)
|
||||
return fouriered
|
||||
|
||||
|
||||
def TimePositionalEmbedding(dim: int, out_features: int) -> nn.Module:
|
||||
return nn.Sequential(
|
||||
LearnedPositionalEmbedding(dim),
|
||||
nn.Linear(in_features=dim + 1, out_features=out_features),
|
||||
)
|
||||
|
||||
class FixedEmbedding(nn.Module):
|
||||
def __init__(self, max_length: int, features: int):
|
||||
super().__init__()
|
||||
self.max_length = max_length
|
||||
self.embedding = nn.Embedding(max_length, features)
|
||||
|
||||
def forward(self, x: Tensor) -> Tensor:
|
||||
batch_size, length, device = *x.shape[0:2], x.device
|
||||
assert_message = "Input sequence length must be <= max_length"
|
||||
assert length <= self.max_length, assert_message
|
||||
position = torch.arange(length, device=device)
|
||||
fixed_embedding = self.embedding(position)
|
||||
fixed_embedding = repeat(fixed_embedding, "n d -> b n d", b=batch_size)
|
||||
return fixed_embedding
|
||||
@@ -0,0 +1,691 @@
|
||||
from math import atan, cos, pi, sin, sqrt
|
||||
from typing import Any, Callable, List, Optional, Tuple, Type
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
from einops import rearrange, reduce
|
||||
from torch import Tensor
|
||||
|
||||
from .utils import *
|
||||
|
||||
"""
|
||||
Diffusion Training
|
||||
"""
|
||||
|
||||
""" Distributions """
|
||||
|
||||
|
||||
class Distribution:
|
||||
def __call__(self, num_samples: int, device: torch.device):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class LogNormalDistribution(Distribution):
|
||||
def __init__(self, mean: float, std: float):
|
||||
self.mean = mean
|
||||
self.std = std
|
||||
|
||||
def __call__(
|
||||
self, num_samples: int, device: torch.device = torch.device("cpu")
|
||||
) -> Tensor:
|
||||
normal = self.mean + self.std * torch.randn((num_samples,), device=device)
|
||||
return normal.exp()
|
||||
|
||||
|
||||
class UniformDistribution(Distribution):
|
||||
def __call__(self, num_samples: int, device: torch.device = torch.device("cpu")):
|
||||
return torch.rand(num_samples, device=device)
|
||||
|
||||
|
||||
class VKDistribution(Distribution):
|
||||
def __init__(
|
||||
self,
|
||||
min_value: float = 0.0,
|
||||
max_value: float = float("inf"),
|
||||
sigma_data: float = 1.0,
|
||||
):
|
||||
self.min_value = min_value
|
||||
self.max_value = max_value
|
||||
self.sigma_data = sigma_data
|
||||
|
||||
def __call__(
|
||||
self, num_samples: int, device: torch.device = torch.device("cpu")
|
||||
) -> Tensor:
|
||||
sigma_data = self.sigma_data
|
||||
min_cdf = atan(self.min_value / sigma_data) * 2 / pi
|
||||
max_cdf = atan(self.max_value / sigma_data) * 2 / pi
|
||||
u = (max_cdf - min_cdf) * torch.randn((num_samples,), device=device) + min_cdf
|
||||
return torch.tan(u * pi / 2) * sigma_data
|
||||
|
||||
|
||||
""" Diffusion Classes """
|
||||
|
||||
|
||||
def pad_dims(x: Tensor, ndim: int) -> Tensor:
|
||||
# Pads additional ndims to the right of the tensor
|
||||
return x.view(*x.shape, *((1,) * ndim))
|
||||
|
||||
|
||||
def clip(x: Tensor, dynamic_threshold: float = 0.0):
|
||||
if dynamic_threshold == 0.0:
|
||||
return x.clamp(-1.0, 1.0)
|
||||
else:
|
||||
# Dynamic thresholding
|
||||
# Find dynamic threshold quantile for each batch
|
||||
x_flat = rearrange(x, "b ... -> b (...)")
|
||||
scale = torch.quantile(x_flat.abs(), dynamic_threshold, dim=-1)
|
||||
# Clamp to a min of 1.0
|
||||
scale.clamp_(min=1.0)
|
||||
# Clamp all values and scale
|
||||
scale = pad_dims(scale, ndim=x.ndim - scale.ndim)
|
||||
x = x.clamp(-scale, scale) / scale
|
||||
return x
|
||||
|
||||
|
||||
def to_batch(
|
||||
batch_size: int,
|
||||
device: torch.device,
|
||||
x: Optional[float] = None,
|
||||
xs: Optional[Tensor] = None,
|
||||
) -> Tensor:
|
||||
assert exists(x) ^ exists(xs), "Either x or xs must be provided"
|
||||
# If x provided use the same for all batch items
|
||||
if exists(x):
|
||||
xs = torch.full(size=(batch_size,), fill_value=x).to(device)
|
||||
assert exists(xs)
|
||||
return xs
|
||||
|
||||
|
||||
class Diffusion(nn.Module):
|
||||
|
||||
alias: str = ""
|
||||
|
||||
"""Base diffusion class"""
|
||||
|
||||
def denoise_fn(
|
||||
self,
|
||||
x_noisy: Tensor,
|
||||
sigmas: Optional[Tensor] = None,
|
||||
sigma: Optional[float] = None,
|
||||
**kwargs,
|
||||
) -> Tensor:
|
||||
raise NotImplementedError("Diffusion class missing denoise_fn")
|
||||
|
||||
def forward(self, x: Tensor, noise: Tensor = None, **kwargs) -> Tensor:
|
||||
raise NotImplementedError("Diffusion class missing forward function")
|
||||
|
||||
|
||||
class VDiffusion(Diffusion):
|
||||
|
||||
alias = "v"
|
||||
|
||||
def __init__(self, net: nn.Module, *, sigma_distribution: Distribution):
|
||||
super().__init__()
|
||||
self.net = net
|
||||
self.sigma_distribution = sigma_distribution
|
||||
|
||||
def get_alpha_beta(self, sigmas: Tensor) -> Tuple[Tensor, Tensor]:
|
||||
angle = sigmas * pi / 2
|
||||
alpha = torch.cos(angle)
|
||||
beta = torch.sin(angle)
|
||||
return alpha, beta
|
||||
|
||||
def denoise_fn(
|
||||
self,
|
||||
x_noisy: Tensor,
|
||||
sigmas: Optional[Tensor] = None,
|
||||
sigma: Optional[float] = None,
|
||||
**kwargs,
|
||||
) -> Tensor:
|
||||
batch_size, device = x_noisy.shape[0], x_noisy.device
|
||||
sigmas = to_batch(x=sigma, xs=sigmas, batch_size=batch_size, device=device)
|
||||
return self.net(x_noisy, sigmas, **kwargs)
|
||||
|
||||
def forward(self, x: Tensor, noise: Tensor = None, **kwargs) -> Tensor:
|
||||
batch_size, device = x.shape[0], x.device
|
||||
|
||||
# Sample amount of noise to add for each batch element
|
||||
sigmas = self.sigma_distribution(num_samples=batch_size, device=device)
|
||||
sigmas_padded = rearrange(sigmas, "b -> b 1 1")
|
||||
|
||||
# Get noise
|
||||
noise = default(noise, lambda: torch.randn_like(x))
|
||||
|
||||
# Combine input and noise weighted by half-circle
|
||||
alpha, beta = self.get_alpha_beta(sigmas_padded)
|
||||
x_noisy = x * alpha + noise * beta
|
||||
x_target = noise * alpha - x * beta
|
||||
|
||||
# Denoise and return loss
|
||||
x_denoised = self.denoise_fn(x_noisy, sigmas, **kwargs)
|
||||
return F.mse_loss(x_denoised, x_target)
|
||||
|
||||
|
||||
class KDiffusion(Diffusion):
|
||||
"""Elucidated Diffusion (Karras et al. 2022): https://arxiv.org/abs/2206.00364"""
|
||||
|
||||
alias = "k"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
net: nn.Module,
|
||||
*,
|
||||
sigma_distribution: Distribution,
|
||||
sigma_data: float, # data distribution standard deviation
|
||||
dynamic_threshold: float = 0.0,
|
||||
):
|
||||
super().__init__()
|
||||
self.net = net
|
||||
self.sigma_data = sigma_data
|
||||
self.sigma_distribution = sigma_distribution
|
||||
self.dynamic_threshold = dynamic_threshold
|
||||
|
||||
def get_scale_weights(self, sigmas: Tensor) -> Tuple[Tensor, ...]:
|
||||
sigma_data = self.sigma_data
|
||||
c_noise = torch.log(sigmas) * 0.25
|
||||
sigmas = rearrange(sigmas, "b -> b 1 1")
|
||||
c_skip = (sigma_data ** 2) / (sigmas ** 2 + sigma_data ** 2)
|
||||
c_out = sigmas * sigma_data * (sigma_data ** 2 + sigmas ** 2) ** -0.5
|
||||
c_in = (sigmas ** 2 + sigma_data ** 2) ** -0.5
|
||||
return c_skip, c_out, c_in, c_noise
|
||||
|
||||
def denoise_fn(
|
||||
self,
|
||||
x_noisy: Tensor,
|
||||
sigmas: Optional[Tensor] = None,
|
||||
sigma: Optional[float] = None,
|
||||
**kwargs,
|
||||
) -> Tensor:
|
||||
batch_size, device = x_noisy.shape[0], x_noisy.device
|
||||
sigmas = to_batch(x=sigma, xs=sigmas, batch_size=batch_size, device=device)
|
||||
|
||||
# Predict network output and add skip connection
|
||||
c_skip, c_out, c_in, c_noise = self.get_scale_weights(sigmas)
|
||||
x_pred = self.net(c_in * x_noisy, c_noise, **kwargs)
|
||||
x_denoised = c_skip * x_noisy + c_out * x_pred
|
||||
|
||||
return x_denoised
|
||||
|
||||
def loss_weight(self, sigmas: Tensor) -> Tensor:
|
||||
# Computes weight depending on data distribution
|
||||
return (sigmas ** 2 + self.sigma_data ** 2) * (sigmas * self.sigma_data) ** -2
|
||||
|
||||
def forward(self, x: Tensor, noise: Tensor = None, **kwargs) -> Tensor:
|
||||
batch_size, device = x.shape[0], x.device
|
||||
from einops import rearrange, reduce
|
||||
|
||||
# Sample amount of noise to add for each batch element
|
||||
sigmas = self.sigma_distribution(num_samples=batch_size, device=device)
|
||||
sigmas_padded = rearrange(sigmas, "b -> b 1 1")
|
||||
|
||||
# Add noise to input
|
||||
noise = default(noise, lambda: torch.randn_like(x))
|
||||
x_noisy = x + sigmas_padded * noise
|
||||
|
||||
# Compute denoised values
|
||||
x_denoised = self.denoise_fn(x_noisy, sigmas=sigmas, **kwargs)
|
||||
|
||||
# Compute weighted loss
|
||||
losses = F.mse_loss(x_denoised, x, reduction="none")
|
||||
losses = reduce(losses, "b ... -> b", "mean")
|
||||
losses = losses * self.loss_weight(sigmas)
|
||||
loss = losses.mean()
|
||||
return loss
|
||||
|
||||
|
||||
class VKDiffusion(Diffusion):
|
||||
|
||||
alias = "vk"
|
||||
|
||||
def __init__(self, net: nn.Module, *, sigma_distribution: Distribution):
|
||||
super().__init__()
|
||||
self.net = net
|
||||
self.sigma_distribution = sigma_distribution
|
||||
|
||||
def get_scale_weights(self, sigmas: Tensor) -> Tuple[Tensor, ...]:
|
||||
sigma_data = 1.0
|
||||
sigmas = rearrange(sigmas, "b -> b 1 1")
|
||||
c_skip = (sigma_data ** 2) / (sigmas ** 2 + sigma_data ** 2)
|
||||
c_out = -sigmas * sigma_data * (sigma_data ** 2 + sigmas ** 2) ** -0.5
|
||||
c_in = (sigmas ** 2 + sigma_data ** 2) ** -0.5
|
||||
return c_skip, c_out, c_in
|
||||
|
||||
def sigma_to_t(self, sigmas: Tensor) -> Tensor:
|
||||
return sigmas.atan() / pi * 2
|
||||
|
||||
def t_to_sigma(self, t: Tensor) -> Tensor:
|
||||
return (t * pi / 2).tan()
|
||||
|
||||
def denoise_fn(
|
||||
self,
|
||||
x_noisy: Tensor,
|
||||
sigmas: Optional[Tensor] = None,
|
||||
sigma: Optional[float] = None,
|
||||
**kwargs,
|
||||
) -> Tensor:
|
||||
batch_size, device = x_noisy.shape[0], x_noisy.device
|
||||
sigmas = to_batch(x=sigma, xs=sigmas, batch_size=batch_size, device=device)
|
||||
|
||||
# Predict network output and add skip connection
|
||||
c_skip, c_out, c_in = self.get_scale_weights(sigmas)
|
||||
x_pred = self.net(c_in * x_noisy, self.sigma_to_t(sigmas), **kwargs)
|
||||
x_denoised = c_skip * x_noisy + c_out * x_pred
|
||||
return x_denoised
|
||||
|
||||
def forward(self, x: Tensor, noise: Tensor = None, **kwargs) -> Tensor:
|
||||
batch_size, device = x.shape[0], x.device
|
||||
|
||||
# Sample amount of noise to add for each batch element
|
||||
sigmas = self.sigma_distribution(num_samples=batch_size, device=device)
|
||||
sigmas_padded = rearrange(sigmas, "b -> b 1 1")
|
||||
|
||||
# Add noise to input
|
||||
noise = default(noise, lambda: torch.randn_like(x))
|
||||
x_noisy = x + sigmas_padded * noise
|
||||
|
||||
# Compute model output
|
||||
c_skip, c_out, c_in = self.get_scale_weights(sigmas)
|
||||
x_pred = self.net(c_in * x_noisy, self.sigma_to_t(sigmas), **kwargs)
|
||||
|
||||
# Compute v-objective target
|
||||
v_target = (x - c_skip * x_noisy) / (c_out + 1e-7)
|
||||
|
||||
# Compute loss
|
||||
loss = F.mse_loss(x_pred, v_target)
|
||||
return loss
|
||||
|
||||
|
||||
"""
|
||||
Diffusion Sampling
|
||||
"""
|
||||
|
||||
""" Schedules """
|
||||
|
||||
|
||||
class Schedule(nn.Module):
|
||||
"""Interface used by different sampling schedules"""
|
||||
|
||||
def forward(self, num_steps: int, device: torch.device) -> Tensor:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class LinearSchedule(Schedule):
|
||||
def forward(self, num_steps: int, device: Any) -> Tensor:
|
||||
sigmas = torch.linspace(1, 0, num_steps + 1)[:-1]
|
||||
return sigmas
|
||||
|
||||
|
||||
class KarrasSchedule(Schedule):
|
||||
"""https://arxiv.org/abs/2206.00364 equation 5"""
|
||||
|
||||
def __init__(self, sigma_min: float, sigma_max: float, rho: float = 7.0):
|
||||
super().__init__()
|
||||
self.sigma_min = sigma_min
|
||||
self.sigma_max = sigma_max
|
||||
self.rho = rho
|
||||
|
||||
def forward(self, num_steps: int, device: Any) -> Tensor:
|
||||
rho_inv = 1.0 / self.rho
|
||||
steps = torch.arange(num_steps, device=device, dtype=torch.float32)
|
||||
sigmas = (
|
||||
self.sigma_max ** rho_inv
|
||||
+ (steps / (num_steps - 1))
|
||||
* (self.sigma_min ** rho_inv - self.sigma_max ** rho_inv)
|
||||
) ** self.rho
|
||||
sigmas = F.pad(sigmas, pad=(0, 1), value=0.0)
|
||||
return sigmas
|
||||
|
||||
|
||||
""" Samplers """
|
||||
|
||||
|
||||
class Sampler(nn.Module):
|
||||
|
||||
diffusion_types: List[Type[Diffusion]] = []
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, fn: Callable, sigmas: Tensor, num_steps: int
|
||||
) -> Tensor:
|
||||
raise NotImplementedError()
|
||||
|
||||
def inpaint(
|
||||
self,
|
||||
source: Tensor,
|
||||
mask: Tensor,
|
||||
fn: Callable,
|
||||
sigmas: Tensor,
|
||||
num_steps: int,
|
||||
num_resamples: int,
|
||||
) -> Tensor:
|
||||
raise NotImplementedError("Inpainting not available with current sampler")
|
||||
|
||||
|
||||
class VSampler(Sampler):
|
||||
|
||||
diffusion_types = [VDiffusion]
|
||||
|
||||
def get_alpha_beta(self, sigma: float) -> Tuple[float, float]:
|
||||
angle = sigma * pi / 2
|
||||
alpha = cos(angle)
|
||||
beta = sin(angle)
|
||||
return alpha, beta
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, fn: Callable, sigmas: Tensor, num_steps: int
|
||||
) -> Tensor:
|
||||
x = sigmas[0] * noise
|
||||
alpha, beta = self.get_alpha_beta(sigmas[0].item())
|
||||
|
||||
for i in range(num_steps - 1):
|
||||
is_last = i == num_steps - 1
|
||||
|
||||
x_denoised = fn(x, sigma=sigmas[i])
|
||||
x_pred = x * alpha - x_denoised * beta
|
||||
x_eps = x * beta + x_denoised * alpha
|
||||
|
||||
if not is_last:
|
||||
alpha, beta = self.get_alpha_beta(sigmas[i + 1].item())
|
||||
x = x_pred * alpha + x_eps * beta
|
||||
|
||||
return x_pred
|
||||
|
||||
|
||||
class KarrasSampler(Sampler):
|
||||
"""https://arxiv.org/abs/2206.00364 algorithm 1"""
|
||||
|
||||
diffusion_types = [KDiffusion, VKDiffusion]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
s_tmin: float = 0,
|
||||
s_tmax: float = float("inf"),
|
||||
s_churn: float = 0.0,
|
||||
s_noise: float = 1.0,
|
||||
):
|
||||
super().__init__()
|
||||
self.s_tmin = s_tmin
|
||||
self.s_tmax = s_tmax
|
||||
self.s_noise = s_noise
|
||||
self.s_churn = s_churn
|
||||
|
||||
def step(
|
||||
self, x: Tensor, fn: Callable, sigma: float, sigma_next: float, gamma: float
|
||||
) -> Tensor:
|
||||
"""Algorithm 2 (step)"""
|
||||
# Select temporarily increased noise level
|
||||
sigma_hat = sigma + gamma * sigma
|
||||
# Add noise to move from sigma to sigma_hat
|
||||
epsilon = self.s_noise * torch.randn_like(x)
|
||||
x_hat = x + sqrt(sigma_hat ** 2 - sigma ** 2) * epsilon
|
||||
# Evaluate ∂x/∂sigma at sigma_hat
|
||||
d = (x_hat - fn(x_hat, sigma=sigma_hat)) / sigma_hat
|
||||
# Take euler step from sigma_hat to sigma_next
|
||||
x_next = x_hat + (sigma_next - sigma_hat) * d
|
||||
# Second order correction
|
||||
if sigma_next != 0:
|
||||
model_out_next = fn(x_next, sigma=sigma_next)
|
||||
d_prime = (x_next - model_out_next) / sigma_next
|
||||
x_next = x_hat + 0.5 * (sigma - sigma_hat) * (d + d_prime)
|
||||
return x_next
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, fn: Callable, sigmas: Tensor, num_steps: int
|
||||
) -> Tensor:
|
||||
x = sigmas[0] * noise
|
||||
# Compute gammas
|
||||
gammas = torch.where(
|
||||
(sigmas >= self.s_tmin) & (sigmas <= self.s_tmax),
|
||||
min(self.s_churn / num_steps, sqrt(2) - 1),
|
||||
0.0,
|
||||
)
|
||||
# Denoise to sample
|
||||
for i in range(num_steps - 1):
|
||||
x = self.step(
|
||||
x, fn=fn, sigma=sigmas[i], sigma_next=sigmas[i + 1], gamma=gammas[i] # type: ignore # noqa
|
||||
)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
class AEulerSampler(Sampler):
|
||||
|
||||
diffusion_types = [KDiffusion, VKDiffusion]
|
||||
|
||||
def get_sigmas(self, sigma: float, sigma_next: float) -> Tuple[float, float]:
|
||||
sigma_up = sqrt(sigma_next ** 2 * (sigma ** 2 - sigma_next ** 2) / sigma ** 2)
|
||||
sigma_down = sqrt(sigma_next ** 2 - sigma_up ** 2)
|
||||
return sigma_up, sigma_down
|
||||
|
||||
def step(self, x: Tensor, fn: Callable, sigma: float, sigma_next: float) -> Tensor:
|
||||
# Sigma steps
|
||||
sigma_up, sigma_down = self.get_sigmas(sigma, sigma_next)
|
||||
# Derivative at sigma (∂x/∂sigma)
|
||||
d = (x - fn(x, sigma=sigma)) / sigma
|
||||
# Euler method
|
||||
x_next = x + d * (sigma_down - sigma)
|
||||
# Add randomness
|
||||
x_next = x_next + torch.randn_like(x) * sigma_up
|
||||
return x_next
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, fn: Callable, sigmas: Tensor, num_steps: int
|
||||
) -> Tensor:
|
||||
x = sigmas[0] * noise
|
||||
# Denoise to sample
|
||||
for i in range(num_steps - 1):
|
||||
x = self.step(x, fn=fn, sigma=sigmas[i], sigma_next=sigmas[i + 1]) # type: ignore # noqa
|
||||
return x
|
||||
|
||||
|
||||
class ADPM2Sampler(Sampler):
|
||||
"""https://www.desmos.com/calculator/jbxjlqd9mb"""
|
||||
|
||||
diffusion_types = [KDiffusion, VKDiffusion]
|
||||
|
||||
def __init__(self, rho: float = 1.0):
|
||||
super().__init__()
|
||||
self.rho = rho
|
||||
|
||||
def get_sigmas(self, sigma: float, sigma_next: float) -> Tuple[float, float, float]:
|
||||
r = self.rho
|
||||
sigma_up = sqrt(sigma_next ** 2 * (sigma ** 2 - sigma_next ** 2) / sigma ** 2)
|
||||
sigma_down = sqrt(sigma_next ** 2 - sigma_up ** 2)
|
||||
sigma_mid = ((sigma ** (1 / r) + sigma_down ** (1 / r)) / 2) ** r
|
||||
return sigma_up, sigma_down, sigma_mid
|
||||
|
||||
def step(self, x: Tensor, fn: Callable, sigma: float, sigma_next: float) -> Tensor:
|
||||
# Sigma steps
|
||||
sigma_up, sigma_down, sigma_mid = self.get_sigmas(sigma, sigma_next)
|
||||
# Derivative at sigma (∂x/∂sigma)
|
||||
d = (x - fn(x, sigma=sigma)) / sigma
|
||||
# Denoise to midpoint
|
||||
x_mid = x + d * (sigma_mid - sigma)
|
||||
# Derivative at sigma_mid (∂x_mid/∂sigma_mid)
|
||||
d_mid = (x_mid - fn(x_mid, sigma=sigma_mid)) / sigma_mid
|
||||
# Denoise to next
|
||||
x = x + d_mid * (sigma_down - sigma)
|
||||
# Add randomness
|
||||
x_next = x + torch.randn_like(x) * sigma_up
|
||||
return x_next
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, fn: Callable, sigmas: Tensor, num_steps: int
|
||||
) -> Tensor:
|
||||
x = sigmas[0] * noise
|
||||
# Denoise to sample
|
||||
for i in range(num_steps - 1):
|
||||
x = self.step(x, fn=fn, sigma=sigmas[i], sigma_next=sigmas[i + 1]) # type: ignore # noqa
|
||||
return x
|
||||
|
||||
def inpaint(
|
||||
self,
|
||||
source: Tensor,
|
||||
mask: Tensor,
|
||||
fn: Callable,
|
||||
sigmas: Tensor,
|
||||
num_steps: int,
|
||||
num_resamples: int,
|
||||
) -> Tensor:
|
||||
x = sigmas[0] * torch.randn_like(source)
|
||||
|
||||
for i in range(num_steps - 1):
|
||||
# Noise source to current noise level
|
||||
source_noisy = source + sigmas[i] * torch.randn_like(source)
|
||||
for r in range(num_resamples):
|
||||
# Merge noisy source and current then denoise
|
||||
x = source_noisy * mask + x * ~mask
|
||||
x = self.step(x, fn=fn, sigma=sigmas[i], sigma_next=sigmas[i + 1]) # type: ignore # noqa
|
||||
# Renoise if not last resample step
|
||||
if r < num_resamples - 1:
|
||||
sigma = sqrt(sigmas[i] ** 2 - sigmas[i + 1] ** 2)
|
||||
x = x + sigma * torch.randn_like(x)
|
||||
|
||||
return source * mask + x * ~mask
|
||||
|
||||
|
||||
""" Main Classes """
|
||||
|
||||
|
||||
class DiffusionSampler(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
diffusion: Diffusion,
|
||||
*,
|
||||
sampler: Sampler,
|
||||
sigma_schedule: Schedule,
|
||||
num_steps: Optional[int] = None,
|
||||
clamp: bool = True,
|
||||
):
|
||||
super().__init__()
|
||||
self.denoise_fn = diffusion.denoise_fn
|
||||
self.sampler = sampler
|
||||
self.sigma_schedule = sigma_schedule
|
||||
self.num_steps = num_steps
|
||||
self.clamp = clamp
|
||||
|
||||
# Check sampler is compatible with diffusion type
|
||||
sampler_class = sampler.__class__.__name__
|
||||
diffusion_class = diffusion.__class__.__name__
|
||||
message = f"{sampler_class} incompatible with {diffusion_class}"
|
||||
assert diffusion.alias in [t.alias for t in sampler.diffusion_types], message
|
||||
|
||||
def forward(
|
||||
self, noise: Tensor, num_steps: Optional[int] = None, **kwargs
|
||||
) -> Tensor:
|
||||
device = noise.device
|
||||
num_steps = default(num_steps, self.num_steps) # type: ignore
|
||||
assert exists(num_steps), "Parameter `num_steps` must be provided"
|
||||
# Compute sigmas using schedule
|
||||
sigmas = self.sigma_schedule(num_steps, device)
|
||||
# Append additional kwargs to denoise function (used e.g. for conditional unet)
|
||||
fn = lambda *a, **ka: self.denoise_fn(*a, **{**ka, **kwargs}) # noqa
|
||||
# Sample using sampler
|
||||
x = self.sampler(noise, fn=fn, sigmas=sigmas, num_steps=num_steps)
|
||||
x = x.clamp(-1.0, 1.0) if self.clamp else x
|
||||
return x
|
||||
|
||||
|
||||
class DiffusionInpainter(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
diffusion: Diffusion,
|
||||
*,
|
||||
num_steps: int,
|
||||
num_resamples: int,
|
||||
sampler: Sampler,
|
||||
sigma_schedule: Schedule,
|
||||
):
|
||||
super().__init__()
|
||||
self.denoise_fn = diffusion.denoise_fn
|
||||
self.num_steps = num_steps
|
||||
self.num_resamples = num_resamples
|
||||
self.inpaint_fn = sampler.inpaint
|
||||
self.sigma_schedule = sigma_schedule
|
||||
|
||||
@torch.no_grad()
|
||||
def forward(self, inpaint: Tensor, inpaint_mask: Tensor) -> Tensor:
|
||||
x = self.inpaint_fn(
|
||||
source=inpaint,
|
||||
mask=inpaint_mask,
|
||||
fn=self.denoise_fn,
|
||||
sigmas=self.sigma_schedule(self.num_steps, inpaint.device),
|
||||
num_steps=self.num_steps,
|
||||
num_resamples=self.num_resamples,
|
||||
)
|
||||
return x
|
||||
|
||||
|
||||
def sequential_mask(like: Tensor, start: int) -> Tensor:
|
||||
length, device = like.shape[2], like.device
|
||||
mask = torch.ones_like(like, dtype=torch.bool)
|
||||
mask[:, :, start:] = torch.zeros((length - start,), device=device)
|
||||
return mask
|
||||
|
||||
|
||||
class SpanBySpanComposer(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
inpainter: DiffusionInpainter,
|
||||
*,
|
||||
num_spans: int,
|
||||
):
|
||||
super().__init__()
|
||||
self.inpainter = inpainter
|
||||
self.num_spans = num_spans
|
||||
|
||||
def forward(self, start: Tensor, keep_start: bool = False) -> Tensor:
|
||||
half_length = start.shape[2] // 2
|
||||
|
||||
spans = list(start.chunk(chunks=2, dim=-1)) if keep_start else []
|
||||
# Inpaint second half from first half
|
||||
inpaint = torch.zeros_like(start)
|
||||
inpaint[:, :, :half_length] = start[:, :, half_length:]
|
||||
inpaint_mask = sequential_mask(like=start, start=half_length)
|
||||
|
||||
for i in range(self.num_spans):
|
||||
# Inpaint second half
|
||||
span = self.inpainter(inpaint=inpaint, inpaint_mask=inpaint_mask)
|
||||
# Replace first half with generated second half
|
||||
second_half = span[:, :, half_length:]
|
||||
inpaint[:, :, :half_length] = second_half
|
||||
# Save generated span
|
||||
spans.append(second_half)
|
||||
|
||||
return torch.cat(spans, dim=2)
|
||||
|
||||
|
||||
class XDiffusion(nn.Module):
|
||||
def __init__(self, type: str, net: nn.Module, **kwargs):
|
||||
super().__init__()
|
||||
|
||||
diffusion_classes = [VDiffusion, KDiffusion, VKDiffusion]
|
||||
aliases = [t.alias for t in diffusion_classes] # type: ignore
|
||||
message = f"type='{type}' must be one of {*aliases,}"
|
||||
assert type in aliases, message
|
||||
self.net = net
|
||||
|
||||
for XDiffusion in diffusion_classes:
|
||||
if XDiffusion.alias == type: # type: ignore
|
||||
self.diffusion = XDiffusion(net=net, **kwargs)
|
||||
|
||||
def forward(self, *args, **kwargs) -> Tensor:
|
||||
return self.diffusion(*args, **kwargs)
|
||||
|
||||
def sample(
|
||||
self,
|
||||
noise: Tensor,
|
||||
num_steps: int,
|
||||
sigma_schedule: Schedule,
|
||||
sampler: Sampler,
|
||||
clamp: bool,
|
||||
**kwargs,
|
||||
) -> Tensor:
|
||||
diffusion_sampler = DiffusionSampler(
|
||||
diffusion=self.diffusion,
|
||||
sampler=sampler,
|
||||
sigma_schedule=sigma_schedule,
|
||||
num_steps=num_steps,
|
||||
clamp=clamp,
|
||||
)
|
||||
return diffusion_sampler(noise, **kwargs)
|
||||
@@ -0,0 +1,82 @@
|
||||
from functools import reduce
|
||||
from inspect import isfunction
|
||||
from math import ceil, floor, log2, pi
|
||||
from typing import Callable, Dict, List, Optional, Sequence, Tuple, TypeVar, Union
|
||||
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
from einops import rearrange
|
||||
from torch import Generator, Tensor
|
||||
from typing_extensions import TypeGuard
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def exists(val: Optional[T]) -> TypeGuard[T]:
|
||||
return val is not None
|
||||
|
||||
|
||||
def iff(condition: bool, value: T) -> Optional[T]:
|
||||
return value if condition else None
|
||||
|
||||
|
||||
def is_sequence(obj: T) -> TypeGuard[Union[list, tuple]]:
|
||||
return isinstance(obj, list) or isinstance(obj, tuple)
|
||||
|
||||
|
||||
def default(val: Optional[T], d: Union[Callable[..., T], T]) -> T:
|
||||
if exists(val):
|
||||
return val
|
||||
return d() if isfunction(d) else d
|
||||
|
||||
|
||||
def to_list(val: Union[T, Sequence[T]]) -> List[T]:
|
||||
if isinstance(val, tuple):
|
||||
return list(val)
|
||||
if isinstance(val, list):
|
||||
return val
|
||||
return [val] # type: ignore
|
||||
|
||||
|
||||
def prod(vals: Sequence[int]) -> int:
|
||||
return reduce(lambda x, y: x * y, vals)
|
||||
|
||||
|
||||
def closest_power_2(x: float) -> int:
|
||||
exponent = log2(x)
|
||||
distance_fn = lambda z: abs(x - 2 ** z) # noqa
|
||||
exponent_closest = min((floor(exponent), ceil(exponent)), key=distance_fn)
|
||||
return 2 ** int(exponent_closest)
|
||||
|
||||
def rand_bool(shape, proba, device = None):
|
||||
if proba == 1:
|
||||
return torch.ones(shape, device=device, dtype=torch.bool)
|
||||
elif proba == 0:
|
||||
return torch.zeros(shape, device=device, dtype=torch.bool)
|
||||
else:
|
||||
return torch.bernoulli(torch.full(shape, proba, device=device)).to(torch.bool)
|
||||
|
||||
|
||||
"""
|
||||
Kwargs Utils
|
||||
"""
|
||||
|
||||
|
||||
def group_dict_by_prefix(prefix: str, d: Dict) -> Tuple[Dict, Dict]:
|
||||
return_dicts: Tuple[Dict, Dict] = ({}, {})
|
||||
for key in d.keys():
|
||||
no_prefix = int(not key.startswith(prefix))
|
||||
return_dicts[no_prefix][key] = d[key]
|
||||
return return_dicts
|
||||
|
||||
|
||||
def groupby(prefix: str, d: Dict, keep_prefix: bool = False) -> Tuple[Dict, Dict]:
|
||||
kwargs_with_prefix, kwargs = group_dict_by_prefix(prefix, d)
|
||||
if keep_prefix:
|
||||
return kwargs_with_prefix, kwargs
|
||||
kwargs_no_prefix = {k[len(prefix) :]: v for k, v in kwargs_with_prefix.items()}
|
||||
return kwargs_no_prefix, kwargs
|
||||
|
||||
|
||||
def prefix_dict(prefix: str, d: Dict) -> Dict:
|
||||
return {prefix + str(k): v for k, v in d.items()}
|
||||
@@ -0,0 +1,188 @@
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
import torch.nn as nn
|
||||
from torch.nn import Conv1d, AvgPool1d, Conv2d
|
||||
from torch.nn.utils import weight_norm, spectral_norm
|
||||
|
||||
from .utils import get_padding
|
||||
|
||||
LRELU_SLOPE = 0.1
|
||||
|
||||
def stft(x, fft_size, hop_size, win_length, window):
|
||||
"""Perform STFT and convert to magnitude spectrogram.
|
||||
Args:
|
||||
x (Tensor): Input signal tensor (B, T).
|
||||
fft_size (int): FFT size.
|
||||
hop_size (int): Hop size.
|
||||
win_length (int): Window length.
|
||||
window (str): Window function type.
|
||||
Returns:
|
||||
Tensor: Magnitude spectrogram (B, #frames, fft_size // 2 + 1).
|
||||
"""
|
||||
x_stft = torch.stft(x, fft_size, hop_size, win_length, window,
|
||||
return_complex=True)
|
||||
real = x_stft[..., 0]
|
||||
imag = x_stft[..., 1]
|
||||
|
||||
return torch.abs(x_stft).transpose(2, 1)
|
||||
|
||||
class SpecDiscriminator(nn.Module):
|
||||
"""docstring for Discriminator."""
|
||||
|
||||
def __init__(self, fft_size=1024, shift_size=120, win_length=600, window="hann_window", use_spectral_norm=False):
|
||||
super(SpecDiscriminator, self).__init__()
|
||||
norm_f = weight_norm if use_spectral_norm == False else spectral_norm
|
||||
self.fft_size = fft_size
|
||||
self.shift_size = shift_size
|
||||
self.win_length = win_length
|
||||
self.window = getattr(torch, window)(win_length)
|
||||
self.discriminators = nn.ModuleList([
|
||||
norm_f(nn.Conv2d(1, 32, kernel_size=(3, 9), padding=(1, 4))),
|
||||
norm_f(nn.Conv2d(32, 32, kernel_size=(3, 9), stride=(1,2), padding=(1, 4))),
|
||||
norm_f(nn.Conv2d(32, 32, kernel_size=(3, 9), stride=(1,2), padding=(1, 4))),
|
||||
norm_f(nn.Conv2d(32, 32, kernel_size=(3, 9), stride=(1,2), padding=(1, 4))),
|
||||
norm_f(nn.Conv2d(32, 32, kernel_size=(3, 3), stride=(1,1), padding=(1, 1))),
|
||||
])
|
||||
|
||||
self.out = norm_f(nn.Conv2d(32, 1, 3, 1, 1))
|
||||
|
||||
def forward(self, y):
|
||||
|
||||
fmap = []
|
||||
y = y.squeeze(1)
|
||||
y = stft(y, self.fft_size, self.shift_size, self.win_length, self.window.to(y.get_device()))
|
||||
y = y.unsqueeze(1)
|
||||
for i, d in enumerate(self.discriminators):
|
||||
y = d(y)
|
||||
y = F.leaky_relu(y, LRELU_SLOPE)
|
||||
fmap.append(y)
|
||||
|
||||
y = self.out(y)
|
||||
fmap.append(y)
|
||||
|
||||
return torch.flatten(y, 1, -1), fmap
|
||||
|
||||
class MultiResSpecDiscriminator(torch.nn.Module):
|
||||
|
||||
def __init__(self,
|
||||
fft_sizes=[1024, 2048, 512],
|
||||
hop_sizes=[120, 240, 50],
|
||||
win_lengths=[600, 1200, 240],
|
||||
window="hann_window"):
|
||||
|
||||
super(MultiResSpecDiscriminator, self).__init__()
|
||||
self.discriminators = nn.ModuleList([
|
||||
SpecDiscriminator(fft_sizes[0], hop_sizes[0], win_lengths[0], window),
|
||||
SpecDiscriminator(fft_sizes[1], hop_sizes[1], win_lengths[1], window),
|
||||
SpecDiscriminator(fft_sizes[2], hop_sizes[2], win_lengths[2], window)
|
||||
])
|
||||
|
||||
def forward(self, y, y_hat):
|
||||
y_d_rs = []
|
||||
y_d_gs = []
|
||||
fmap_rs = []
|
||||
fmap_gs = []
|
||||
for i, d in enumerate(self.discriminators):
|
||||
y_d_r, fmap_r = d(y)
|
||||
y_d_g, fmap_g = d(y_hat)
|
||||
y_d_rs.append(y_d_r)
|
||||
fmap_rs.append(fmap_r)
|
||||
y_d_gs.append(y_d_g)
|
||||
fmap_gs.append(fmap_g)
|
||||
|
||||
return y_d_rs, y_d_gs, fmap_rs, fmap_gs
|
||||
|
||||
|
||||
class DiscriminatorP(torch.nn.Module):
|
||||
def __init__(self, period, kernel_size=5, stride=3, use_spectral_norm=False):
|
||||
super(DiscriminatorP, self).__init__()
|
||||
self.period = period
|
||||
norm_f = weight_norm if use_spectral_norm == False else spectral_norm
|
||||
self.convs = nn.ModuleList([
|
||||
norm_f(Conv2d(1, 32, (kernel_size, 1), (stride, 1), padding=(get_padding(5, 1), 0))),
|
||||
norm_f(Conv2d(32, 128, (kernel_size, 1), (stride, 1), padding=(get_padding(5, 1), 0))),
|
||||
norm_f(Conv2d(128, 512, (kernel_size, 1), (stride, 1), padding=(get_padding(5, 1), 0))),
|
||||
norm_f(Conv2d(512, 1024, (kernel_size, 1), (stride, 1), padding=(get_padding(5, 1), 0))),
|
||||
norm_f(Conv2d(1024, 1024, (kernel_size, 1), 1, padding=(2, 0))),
|
||||
])
|
||||
self.conv_post = norm_f(Conv2d(1024, 1, (3, 1), 1, padding=(1, 0)))
|
||||
|
||||
def forward(self, x):
|
||||
fmap = []
|
||||
|
||||
# 1d to 2d
|
||||
b, c, t = x.shape
|
||||
if t % self.period != 0: # pad first
|
||||
n_pad = self.period - (t % self.period)
|
||||
x = F.pad(x, (0, n_pad), "reflect")
|
||||
t = t + n_pad
|
||||
x = x.view(b, c, t // self.period, self.period)
|
||||
|
||||
for l in self.convs:
|
||||
x = l(x)
|
||||
x = F.leaky_relu(x, LRELU_SLOPE)
|
||||
fmap.append(x)
|
||||
x = self.conv_post(x)
|
||||
fmap.append(x)
|
||||
x = torch.flatten(x, 1, -1)
|
||||
|
||||
return x, fmap
|
||||
|
||||
|
||||
class MultiPeriodDiscriminator(torch.nn.Module):
|
||||
def __init__(self):
|
||||
super(MultiPeriodDiscriminator, self).__init__()
|
||||
self.discriminators = nn.ModuleList([
|
||||
DiscriminatorP(2),
|
||||
DiscriminatorP(3),
|
||||
DiscriminatorP(5),
|
||||
DiscriminatorP(7),
|
||||
DiscriminatorP(11),
|
||||
])
|
||||
|
||||
def forward(self, y, y_hat):
|
||||
y_d_rs = []
|
||||
y_d_gs = []
|
||||
fmap_rs = []
|
||||
fmap_gs = []
|
||||
for i, d in enumerate(self.discriminators):
|
||||
y_d_r, fmap_r = d(y)
|
||||
y_d_g, fmap_g = d(y_hat)
|
||||
y_d_rs.append(y_d_r)
|
||||
fmap_rs.append(fmap_r)
|
||||
y_d_gs.append(y_d_g)
|
||||
fmap_gs.append(fmap_g)
|
||||
|
||||
return y_d_rs, y_d_gs, fmap_rs, fmap_gs
|
||||
|
||||
class WavLMDiscriminator(nn.Module):
|
||||
"""docstring for Discriminator."""
|
||||
|
||||
def __init__(self, slm_hidden=768,
|
||||
slm_layers=13,
|
||||
initial_channel=64,
|
||||
use_spectral_norm=False):
|
||||
super(WavLMDiscriminator, self).__init__()
|
||||
norm_f = weight_norm if use_spectral_norm == False else spectral_norm
|
||||
self.pre = norm_f(Conv1d(slm_hidden * slm_layers, initial_channel, 1, 1, padding=0))
|
||||
|
||||
self.convs = nn.ModuleList([
|
||||
norm_f(nn.Conv1d(initial_channel, initial_channel * 2, kernel_size=5, padding=2)),
|
||||
norm_f(nn.Conv1d(initial_channel * 2, initial_channel * 4, kernel_size=5, padding=2)),
|
||||
norm_f(nn.Conv1d(initial_channel * 4, initial_channel * 4, 5, 1, padding=2)),
|
||||
])
|
||||
|
||||
self.conv_post = norm_f(Conv1d(initial_channel * 4, 1, 3, 1, padding=1))
|
||||
|
||||
def forward(self, x):
|
||||
x = self.pre(x)
|
||||
|
||||
fmap = []
|
||||
for l in self.convs:
|
||||
x = l(x)
|
||||
x = F.leaky_relu(x, LRELU_SLOPE)
|
||||
fmap.append(x)
|
||||
x = self.conv_post(x)
|
||||
x = torch.flatten(x, 1, -1)
|
||||
|
||||
return x
|
||||
@@ -0,0 +1,477 @@
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
import torch.nn as nn
|
||||
from torch.nn import Conv1d, ConvTranspose1d, AvgPool1d, Conv2d
|
||||
from torch.nn.utils import weight_norm, remove_weight_norm, spectral_norm
|
||||
from .utils import init_weights, get_padding
|
||||
|
||||
import math
|
||||
import random
|
||||
import numpy as np
|
||||
|
||||
LRELU_SLOPE = 0.1
|
||||
|
||||
class AdaIN1d(nn.Module):
|
||||
def __init__(self, style_dim, num_features):
|
||||
super().__init__()
|
||||
self.norm = nn.InstanceNorm1d(num_features, affine=False)
|
||||
self.fc = nn.Linear(style_dim, num_features*2)
|
||||
|
||||
def forward(self, x, s):
|
||||
h = self.fc(s)
|
||||
h = h.view(h.size(0), h.size(1), 1)
|
||||
gamma, beta = torch.chunk(h, chunks=2, dim=1)
|
||||
return (1 + gamma) * self.norm(x) + beta
|
||||
|
||||
class AdaINResBlock1(torch.nn.Module):
|
||||
def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5), style_dim=64):
|
||||
super(AdaINResBlock1, self).__init__()
|
||||
self.convs1 = nn.ModuleList([
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[0],
|
||||
padding=get_padding(kernel_size, dilation[0]))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[1],
|
||||
padding=get_padding(kernel_size, dilation[1]))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[2],
|
||||
padding=get_padding(kernel_size, dilation[2])))
|
||||
])
|
||||
self.convs1.apply(init_weights)
|
||||
|
||||
self.convs2 = nn.ModuleList([
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1)))
|
||||
])
|
||||
self.convs2.apply(init_weights)
|
||||
|
||||
self.adain1 = nn.ModuleList([
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
])
|
||||
|
||||
self.adain2 = nn.ModuleList([
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
])
|
||||
|
||||
self.alpha1 = nn.ParameterList([nn.Parameter(torch.ones(1, channels, 1)) for i in range(len(self.convs1))])
|
||||
self.alpha2 = nn.ParameterList([nn.Parameter(torch.ones(1, channels, 1)) for i in range(len(self.convs2))])
|
||||
|
||||
|
||||
def forward(self, x, s):
|
||||
for c1, c2, n1, n2, a1, a2 in zip(self.convs1, self.convs2, self.adain1, self.adain2, self.alpha1, self.alpha2):
|
||||
xt = n1(x, s)
|
||||
xt = xt + (1 / a1) * (torch.sin(a1 * xt) ** 2) # Snake1D
|
||||
xt = c1(xt)
|
||||
xt = n2(xt, s)
|
||||
xt = xt + (1 / a2) * (torch.sin(a2 * xt) ** 2) # Snake1D
|
||||
xt = c2(xt)
|
||||
x = xt + x
|
||||
return x
|
||||
|
||||
def remove_weight_norm(self):
|
||||
for l in self.convs1:
|
||||
remove_weight_norm(l)
|
||||
for l in self.convs2:
|
||||
remove_weight_norm(l)
|
||||
|
||||
class SineGen(torch.nn.Module):
|
||||
""" Definition of sine generator
|
||||
SineGen(samp_rate, harmonic_num = 0,
|
||||
sine_amp = 0.1, noise_std = 0.003,
|
||||
voiced_threshold = 0,
|
||||
flag_for_pulse=False)
|
||||
samp_rate: sampling rate in Hz
|
||||
harmonic_num: number of harmonic overtones (default 0)
|
||||
sine_amp: amplitude of sine-wavefrom (default 0.1)
|
||||
noise_std: std of Gaussian noise (default 0.003)
|
||||
voiced_thoreshold: F0 threshold for U/V classification (default 0)
|
||||
flag_for_pulse: this SinGen is used inside PulseGen (default False)
|
||||
Note: when flag_for_pulse is True, the first time step of a voiced
|
||||
segment is always sin(np.pi) or cos(0)
|
||||
"""
|
||||
|
||||
def __init__(self, samp_rate, upsample_scale, harmonic_num=0,
|
||||
sine_amp=0.1, noise_std=0.003,
|
||||
voiced_threshold=0,
|
||||
flag_for_pulse=False):
|
||||
super(SineGen, self).__init__()
|
||||
self.sine_amp = sine_amp
|
||||
self.noise_std = noise_std
|
||||
self.harmonic_num = harmonic_num
|
||||
self.dim = self.harmonic_num + 1
|
||||
self.sampling_rate = samp_rate
|
||||
self.voiced_threshold = voiced_threshold
|
||||
self.flag_for_pulse = flag_for_pulse
|
||||
self.upsample_scale = upsample_scale
|
||||
|
||||
def _f02uv(self, f0):
|
||||
# generate uv signal
|
||||
uv = (f0 > self.voiced_threshold).type(torch.float32)
|
||||
return uv
|
||||
|
||||
def _f02sine(self, f0_values):
|
||||
""" f0_values: (batchsize, length, dim)
|
||||
where dim indicates fundamental tone and overtones
|
||||
"""
|
||||
# convert to F0 in rad. The interger part n can be ignored
|
||||
# because 2 * np.pi * n doesn't affect phase
|
||||
rad_values = (f0_values / self.sampling_rate) % 1
|
||||
|
||||
# initial phase noise (no noise for fundamental component)
|
||||
rand_ini = torch.rand(f0_values.shape[0], f0_values.shape[2], \
|
||||
device=f0_values.device)
|
||||
rand_ini[:, 0] = 0
|
||||
rad_values[:, 0, :] = rad_values[:, 0, :] + rand_ini
|
||||
|
||||
# instantanouse phase sine[t] = sin(2*pi \sum_i=1 ^{t} rad)
|
||||
if not self.flag_for_pulse:
|
||||
# # for normal case
|
||||
|
||||
# # To prevent torch.cumsum numerical overflow,
|
||||
# # it is necessary to add -1 whenever \sum_k=1^n rad_value_k > 1.
|
||||
# # Buffer tmp_over_one_idx indicates the time step to add -1.
|
||||
# # This will not change F0 of sine because (x-1) * 2*pi = x * 2*pi
|
||||
# tmp_over_one = torch.cumsum(rad_values, 1) % 1
|
||||
# tmp_over_one_idx = (padDiff(tmp_over_one)) < 0
|
||||
# cumsum_shift = torch.zeros_like(rad_values)
|
||||
# cumsum_shift[:, 1:, :] = tmp_over_one_idx * -1.0
|
||||
|
||||
# phase = torch.cumsum(rad_values, dim=1) * 2 * np.pi
|
||||
rad_values = torch.nn.functional.interpolate(rad_values.transpose(1, 2),
|
||||
scale_factor=1/self.upsample_scale,
|
||||
mode="linear").transpose(1, 2)
|
||||
|
||||
# tmp_over_one = torch.cumsum(rad_values, 1) % 1
|
||||
# tmp_over_one_idx = (padDiff(tmp_over_one)) < 0
|
||||
# cumsum_shift = torch.zeros_like(rad_values)
|
||||
# cumsum_shift[:, 1:, :] = tmp_over_one_idx * -1.0
|
||||
|
||||
phase = torch.cumsum(rad_values, dim=1) * 2 * np.pi
|
||||
phase = torch.nn.functional.interpolate(phase.transpose(1, 2) * self.upsample_scale,
|
||||
scale_factor=self.upsample_scale, mode="linear").transpose(1, 2)
|
||||
sines = torch.sin(phase)
|
||||
|
||||
else:
|
||||
# If necessary, make sure that the first time step of every
|
||||
# voiced segments is sin(pi) or cos(0)
|
||||
# This is used for pulse-train generation
|
||||
|
||||
# identify the last time step in unvoiced segments
|
||||
uv = self._f02uv(f0_values)
|
||||
uv_1 = torch.roll(uv, shifts=-1, dims=1)
|
||||
uv_1[:, -1, :] = 1
|
||||
u_loc = (uv < 1) * (uv_1 > 0)
|
||||
|
||||
# get the instantanouse phase
|
||||
tmp_cumsum = torch.cumsum(rad_values, dim=1)
|
||||
# different batch needs to be processed differently
|
||||
for idx in range(f0_values.shape[0]):
|
||||
temp_sum = tmp_cumsum[idx, u_loc[idx, :, 0], :]
|
||||
temp_sum[1:, :] = temp_sum[1:, :] - temp_sum[0:-1, :]
|
||||
# stores the accumulation of i.phase within
|
||||
# each voiced segments
|
||||
tmp_cumsum[idx, :, :] = 0
|
||||
tmp_cumsum[idx, u_loc[idx, :, 0], :] = temp_sum
|
||||
|
||||
# rad_values - tmp_cumsum: remove the accumulation of i.phase
|
||||
# within the previous voiced segment.
|
||||
i_phase = torch.cumsum(rad_values - tmp_cumsum, dim=1)
|
||||
|
||||
# get the sines
|
||||
sines = torch.cos(i_phase * 2 * np.pi)
|
||||
return sines
|
||||
|
||||
def forward(self, f0):
|
||||
""" sine_tensor, uv = forward(f0)
|
||||
input F0: tensor(batchsize=1, length, dim=1)
|
||||
f0 for unvoiced steps should be 0
|
||||
output sine_tensor: tensor(batchsize=1, length, dim)
|
||||
output uv: tensor(batchsize=1, length, 1)
|
||||
"""
|
||||
f0_buf = torch.zeros(f0.shape[0], f0.shape[1], self.dim,
|
||||
device=f0.device)
|
||||
# fundamental component
|
||||
fn = torch.multiply(f0, torch.FloatTensor([[range(1, self.harmonic_num + 2)]]).to(f0.device))
|
||||
|
||||
# generate sine waveforms
|
||||
sine_waves = self._f02sine(fn) * self.sine_amp
|
||||
|
||||
# generate uv signal
|
||||
# uv = torch.ones(f0.shape)
|
||||
# uv = uv * (f0 > self.voiced_threshold)
|
||||
uv = self._f02uv(f0)
|
||||
|
||||
# noise: for unvoiced should be similar to sine_amp
|
||||
# std = self.sine_amp/3 -> max value ~ self.sine_amp
|
||||
# . for voiced regions is self.noise_std
|
||||
noise_amp = uv * self.noise_std + (1 - uv) * self.sine_amp / 3
|
||||
noise = noise_amp * torch.randn_like(sine_waves)
|
||||
|
||||
# first: set the unvoiced part to 0 by uv
|
||||
# then: additive noise
|
||||
sine_waves = sine_waves * uv + noise
|
||||
return sine_waves, uv, noise
|
||||
|
||||
|
||||
class SourceModuleHnNSF(torch.nn.Module):
|
||||
""" SourceModule for hn-nsf
|
||||
SourceModule(sampling_rate, harmonic_num=0, sine_amp=0.1,
|
||||
add_noise_std=0.003, voiced_threshod=0)
|
||||
sampling_rate: sampling_rate in Hz
|
||||
harmonic_num: number of harmonic above F0 (default: 0)
|
||||
sine_amp: amplitude of sine source signal (default: 0.1)
|
||||
add_noise_std: std of additive Gaussian noise (default: 0.003)
|
||||
note that amplitude of noise in unvoiced is decided
|
||||
by sine_amp
|
||||
voiced_threshold: threhold to set U/V given F0 (default: 0)
|
||||
Sine_source, noise_source = SourceModuleHnNSF(F0_sampled)
|
||||
F0_sampled (batchsize, length, 1)
|
||||
Sine_source (batchsize, length, 1)
|
||||
noise_source (batchsize, length 1)
|
||||
uv (batchsize, length, 1)
|
||||
"""
|
||||
|
||||
def __init__(self, sampling_rate, upsample_scale, harmonic_num=0, sine_amp=0.1,
|
||||
add_noise_std=0.003, voiced_threshod=0):
|
||||
super(SourceModuleHnNSF, self).__init__()
|
||||
|
||||
self.sine_amp = sine_amp
|
||||
self.noise_std = add_noise_std
|
||||
|
||||
# to produce sine waveforms
|
||||
self.l_sin_gen = SineGen(sampling_rate, upsample_scale, harmonic_num,
|
||||
sine_amp, add_noise_std, voiced_threshod)
|
||||
|
||||
# to merge source harmonics into a single excitation
|
||||
self.l_linear = torch.nn.Linear(harmonic_num + 1, 1)
|
||||
self.l_tanh = torch.nn.Tanh()
|
||||
|
||||
def forward(self, x):
|
||||
"""
|
||||
Sine_source, noise_source = SourceModuleHnNSF(F0_sampled)
|
||||
F0_sampled (batchsize, length, 1)
|
||||
Sine_source (batchsize, length, 1)
|
||||
noise_source (batchsize, length 1)
|
||||
"""
|
||||
# source for harmonic branch
|
||||
with torch.no_grad():
|
||||
sine_wavs, uv, _ = self.l_sin_gen(x)
|
||||
sine_merge = self.l_tanh(self.l_linear(sine_wavs))
|
||||
|
||||
# source for noise branch, in the same shape as uv
|
||||
noise = torch.randn_like(uv) * self.sine_amp / 3
|
||||
return sine_merge, noise, uv
|
||||
def padDiff(x):
|
||||
return F.pad(F.pad(x, (0,0,-1,1), 'constant', 0) - x, (0,0,0,-1), 'constant', 0)
|
||||
|
||||
class Generator(torch.nn.Module):
|
||||
def __init__(self, style_dim, resblock_kernel_sizes, upsample_rates, upsample_initial_channel, resblock_dilation_sizes, upsample_kernel_sizes):
|
||||
super(Generator, self).__init__()
|
||||
self.num_kernels = len(resblock_kernel_sizes)
|
||||
self.num_upsamples = len(upsample_rates)
|
||||
resblock = AdaINResBlock1
|
||||
|
||||
self.m_source = SourceModuleHnNSF(
|
||||
sampling_rate=24000,
|
||||
upsample_scale=np.prod(upsample_rates),
|
||||
harmonic_num=8, voiced_threshod=10)
|
||||
|
||||
self.f0_upsamp = torch.nn.Upsample(scale_factor=np.prod(upsample_rates))
|
||||
self.noise_convs = nn.ModuleList()
|
||||
self.ups = nn.ModuleList()
|
||||
self.noise_res = nn.ModuleList()
|
||||
|
||||
for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)):
|
||||
c_cur = upsample_initial_channel // (2 ** (i + 1))
|
||||
|
||||
self.ups.append(weight_norm(ConvTranspose1d(upsample_initial_channel//(2**i),
|
||||
upsample_initial_channel//(2**(i+1)),
|
||||
k, u, padding=(u//2 + u%2), output_padding=u%2)))
|
||||
|
||||
if i + 1 < len(upsample_rates): #
|
||||
stride_f0 = np.prod(upsample_rates[i + 1:])
|
||||
self.noise_convs.append(Conv1d(
|
||||
1, c_cur, kernel_size=stride_f0 * 2, stride=stride_f0, padding=(stride_f0+1) // 2))
|
||||
self.noise_res.append(resblock(c_cur, 7, [1,3,5], style_dim))
|
||||
else:
|
||||
self.noise_convs.append(Conv1d(1, c_cur, kernel_size=1))
|
||||
self.noise_res.append(resblock(c_cur, 11, [1,3,5], style_dim))
|
||||
|
||||
self.resblocks = nn.ModuleList()
|
||||
|
||||
self.alphas = nn.ParameterList()
|
||||
self.alphas.append(nn.Parameter(torch.ones(1, upsample_initial_channel, 1)))
|
||||
|
||||
for i in range(len(self.ups)):
|
||||
ch = upsample_initial_channel//(2**(i+1))
|
||||
self.alphas.append(nn.Parameter(torch.ones(1, ch, 1)))
|
||||
|
||||
for j, (k, d) in enumerate(zip(resblock_kernel_sizes, resblock_dilation_sizes)):
|
||||
self.resblocks.append(resblock(ch, k, d, style_dim))
|
||||
|
||||
self.conv_post = weight_norm(Conv1d(ch, 1, 7, 1, padding=3))
|
||||
self.ups.apply(init_weights)
|
||||
self.conv_post.apply(init_weights)
|
||||
|
||||
def forward(self, x, s, f0):
|
||||
|
||||
f0 = self.f0_upsamp(f0[:, None]).transpose(1, 2) # bs,n,t
|
||||
|
||||
har_source, noi_source, uv = self.m_source(f0)
|
||||
har_source = har_source.transpose(1, 2)
|
||||
|
||||
for i in range(self.num_upsamples):
|
||||
x = x + (1 / self.alphas[i]) * (torch.sin(self.alphas[i] * x) ** 2)
|
||||
x_source = self.noise_convs[i](har_source)
|
||||
x_source = self.noise_res[i](x_source, s)
|
||||
|
||||
x = self.ups[i](x)
|
||||
x = x + x_source
|
||||
|
||||
xs = None
|
||||
for j in range(self.num_kernels):
|
||||
if xs is None:
|
||||
xs = self.resblocks[i*self.num_kernels+j](x, s)
|
||||
else:
|
||||
xs += self.resblocks[i*self.num_kernels+j](x, s)
|
||||
x = xs / self.num_kernels
|
||||
x = x + (1 / self.alphas[i+1]) * (torch.sin(self.alphas[i+1] * x) ** 2)
|
||||
x = self.conv_post(x)
|
||||
x = torch.tanh(x)
|
||||
|
||||
return x
|
||||
|
||||
def remove_weight_norm(self):
|
||||
print('Removing weight norm...')
|
||||
for l in self.ups:
|
||||
remove_weight_norm(l)
|
||||
for l in self.resblocks:
|
||||
l.remove_weight_norm()
|
||||
remove_weight_norm(self.conv_pre)
|
||||
remove_weight_norm(self.conv_post)
|
||||
|
||||
|
||||
class AdainResBlk1d(nn.Module):
|
||||
def __init__(self, dim_in, dim_out, style_dim=64, actv=nn.LeakyReLU(0.2),
|
||||
upsample='none', dropout_p=0.0):
|
||||
super().__init__()
|
||||
self.actv = actv
|
||||
self.upsample_type = upsample
|
||||
self.upsample = UpSample1d(upsample)
|
||||
self.learned_sc = dim_in != dim_out
|
||||
self._build_weights(dim_in, dim_out, style_dim)
|
||||
self.dropout = nn.Dropout(dropout_p)
|
||||
|
||||
if upsample == 'none':
|
||||
self.pool = nn.Identity()
|
||||
else:
|
||||
self.pool = weight_norm(nn.ConvTranspose1d(dim_in, dim_in, kernel_size=3, stride=2, groups=dim_in, padding=1, output_padding=1))
|
||||
|
||||
|
||||
def _build_weights(self, dim_in, dim_out, style_dim):
|
||||
self.conv1 = weight_norm(nn.Conv1d(dim_in, dim_out, 3, 1, 1))
|
||||
self.conv2 = weight_norm(nn.Conv1d(dim_out, dim_out, 3, 1, 1))
|
||||
self.norm1 = AdaIN1d(style_dim, dim_in)
|
||||
self.norm2 = AdaIN1d(style_dim, dim_out)
|
||||
if self.learned_sc:
|
||||
self.conv1x1 = weight_norm(nn.Conv1d(dim_in, dim_out, 1, 1, 0, bias=False))
|
||||
|
||||
def _shortcut(self, x):
|
||||
x = self.upsample(x)
|
||||
if self.learned_sc:
|
||||
x = self.conv1x1(x)
|
||||
return x
|
||||
|
||||
def _residual(self, x, s):
|
||||
x = self.norm1(x, s)
|
||||
x = self.actv(x)
|
||||
x = self.pool(x)
|
||||
x = self.conv1(self.dropout(x))
|
||||
x = self.norm2(x, s)
|
||||
x = self.actv(x)
|
||||
x = self.conv2(self.dropout(x))
|
||||
return x
|
||||
|
||||
def forward(self, x, s):
|
||||
out = self._residual(x, s)
|
||||
out = (out + self._shortcut(x)) / math.sqrt(2)
|
||||
return out
|
||||
|
||||
class UpSample1d(nn.Module):
|
||||
def __init__(self, layer_type):
|
||||
super().__init__()
|
||||
self.layer_type = layer_type
|
||||
|
||||
def forward(self, x):
|
||||
if self.layer_type == 'none':
|
||||
return x
|
||||
else:
|
||||
return F.interpolate(x, scale_factor=2, mode='nearest')
|
||||
|
||||
class Decoder(nn.Module):
|
||||
def __init__(self, dim_in=512, F0_channel=512, style_dim=64, dim_out=80,
|
||||
resblock_kernel_sizes = [3,7,11],
|
||||
upsample_rates = [10,5,3,2],
|
||||
upsample_initial_channel=512,
|
||||
resblock_dilation_sizes=[[1,3,5], [1,3,5], [1,3,5]],
|
||||
upsample_kernel_sizes=[20,10,6,4]):
|
||||
super().__init__()
|
||||
|
||||
self.decode = nn.ModuleList()
|
||||
|
||||
self.encode = AdainResBlk1d(dim_in + 2, 1024, style_dim)
|
||||
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 512, style_dim, upsample=True))
|
||||
|
||||
self.F0_conv = weight_norm(nn.Conv1d(1, 1, kernel_size=3, stride=2, groups=1, padding=1))
|
||||
|
||||
self.N_conv = weight_norm(nn.Conv1d(1, 1, kernel_size=3, stride=2, groups=1, padding=1))
|
||||
|
||||
self.asr_res = nn.Sequential(
|
||||
weight_norm(nn.Conv1d(512, 64, kernel_size=1)),
|
||||
)
|
||||
|
||||
|
||||
self.generator = Generator(style_dim, resblock_kernel_sizes, upsample_rates, upsample_initial_channel, resblock_dilation_sizes, upsample_kernel_sizes)
|
||||
|
||||
|
||||
def forward(self, asr, F0_curve, N, s):
|
||||
if self.training:
|
||||
downlist = [0, 3, 7]
|
||||
F0_down = downlist[random.randint(0, 2)]
|
||||
downlist = [0, 3, 7, 15]
|
||||
N_down = downlist[random.randint(0, 3)]
|
||||
if F0_down:
|
||||
F0_curve = nn.functional.conv1d(F0_curve.unsqueeze(1), torch.ones(1, 1, F0_down).to('cuda'), padding=F0_down//2).squeeze(1) / F0_down
|
||||
if N_down:
|
||||
N = nn.functional.conv1d(N.unsqueeze(1), torch.ones(1, 1, N_down).to('cuda'), padding=N_down//2).squeeze(1) / N_down
|
||||
|
||||
|
||||
F0 = self.F0_conv(F0_curve.unsqueeze(1))
|
||||
N = self.N_conv(N.unsqueeze(1))
|
||||
|
||||
x = torch.cat([asr, F0, N], axis=1)
|
||||
x = self.encode(x, s)
|
||||
|
||||
asr_res = self.asr_res(asr)
|
||||
|
||||
res = True
|
||||
for block in self.decode:
|
||||
if res:
|
||||
x = torch.cat([x, asr_res, F0, N], axis=1)
|
||||
x = block(x, s)
|
||||
if block.upsample_type != "none":
|
||||
res = False
|
||||
|
||||
x = self.generator(x, s, F0_curve)
|
||||
return x
|
||||
|
||||
|
||||
@@ -0,0 +1,530 @@
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
import torch.nn as nn
|
||||
from torch.nn import Conv1d, ConvTranspose1d, AvgPool1d, Conv2d
|
||||
from torch.nn.utils import weight_norm, remove_weight_norm, spectral_norm
|
||||
from .utils import init_weights, get_padding
|
||||
|
||||
import math
|
||||
import random
|
||||
import numpy as np
|
||||
from scipy.signal import get_window
|
||||
|
||||
LRELU_SLOPE = 0.1
|
||||
|
||||
class AdaIN1d(nn.Module):
|
||||
def __init__(self, style_dim, num_features):
|
||||
super().__init__()
|
||||
self.norm = nn.InstanceNorm1d(num_features, affine=False)
|
||||
self.fc = nn.Linear(style_dim, num_features*2)
|
||||
|
||||
def forward(self, x, s):
|
||||
h = self.fc(s)
|
||||
h = h.view(h.size(0), h.size(1), 1)
|
||||
gamma, beta = torch.chunk(h, chunks=2, dim=1)
|
||||
return (1 + gamma) * self.norm(x) + beta
|
||||
|
||||
class AdaINResBlock1(torch.nn.Module):
|
||||
def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5), style_dim=64):
|
||||
super(AdaINResBlock1, self).__init__()
|
||||
self.convs1 = nn.ModuleList([
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[0],
|
||||
padding=get_padding(kernel_size, dilation[0]))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[1],
|
||||
padding=get_padding(kernel_size, dilation[1]))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[2],
|
||||
padding=get_padding(kernel_size, dilation[2])))
|
||||
])
|
||||
self.convs1.apply(init_weights)
|
||||
|
||||
self.convs2 = nn.ModuleList([
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1))),
|
||||
weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
|
||||
padding=get_padding(kernel_size, 1)))
|
||||
])
|
||||
self.convs2.apply(init_weights)
|
||||
|
||||
self.adain1 = nn.ModuleList([
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
])
|
||||
|
||||
self.adain2 = nn.ModuleList([
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
AdaIN1d(style_dim, channels),
|
||||
])
|
||||
|
||||
self.alpha1 = nn.ParameterList([nn.Parameter(torch.ones(1, channels, 1)) for i in range(len(self.convs1))])
|
||||
self.alpha2 = nn.ParameterList([nn.Parameter(torch.ones(1, channels, 1)) for i in range(len(self.convs2))])
|
||||
|
||||
|
||||
def forward(self, x, s):
|
||||
for c1, c2, n1, n2, a1, a2 in zip(self.convs1, self.convs2, self.adain1, self.adain2, self.alpha1, self.alpha2):
|
||||
xt = n1(x, s)
|
||||
xt = xt + (1 / a1) * (torch.sin(a1 * xt) ** 2) # Snake1D
|
||||
xt = c1(xt)
|
||||
xt = n2(xt, s)
|
||||
xt = xt + (1 / a2) * (torch.sin(a2 * xt) ** 2) # Snake1D
|
||||
xt = c2(xt)
|
||||
x = xt + x
|
||||
return x
|
||||
|
||||
def remove_weight_norm(self):
|
||||
for l in self.convs1:
|
||||
remove_weight_norm(l)
|
||||
for l in self.convs2:
|
||||
remove_weight_norm(l)
|
||||
|
||||
class TorchSTFT(torch.nn.Module):
|
||||
def __init__(self, filter_length=800, hop_length=200, win_length=800, window='hann'):
|
||||
super().__init__()
|
||||
self.filter_length = filter_length
|
||||
self.hop_length = hop_length
|
||||
self.win_length = win_length
|
||||
self.window = torch.from_numpy(get_window(window, win_length, fftbins=True).astype(np.float32))
|
||||
|
||||
def transform(self, input_data):
|
||||
forward_transform = torch.stft(
|
||||
input_data,
|
||||
self.filter_length, self.hop_length, self.win_length, window=self.window.to(input_data.device),
|
||||
return_complex=True)
|
||||
|
||||
return torch.abs(forward_transform), torch.angle(forward_transform)
|
||||
|
||||
def inverse(self, magnitude, phase):
|
||||
inverse_transform = torch.istft(
|
||||
magnitude * torch.exp(phase * 1j),
|
||||
self.filter_length, self.hop_length, self.win_length, window=self.window.to(magnitude.device))
|
||||
|
||||
return inverse_transform.unsqueeze(-2) # unsqueeze to stay consistent with conv_transpose1d implementation
|
||||
|
||||
def forward(self, input_data):
|
||||
self.magnitude, self.phase = self.transform(input_data)
|
||||
reconstruction = self.inverse(self.magnitude, self.phase)
|
||||
return reconstruction
|
||||
|
||||
class SineGen(torch.nn.Module):
|
||||
""" Definition of sine generator
|
||||
SineGen(samp_rate, harmonic_num = 0,
|
||||
sine_amp = 0.1, noise_std = 0.003,
|
||||
voiced_threshold = 0,
|
||||
flag_for_pulse=False)
|
||||
samp_rate: sampling rate in Hz
|
||||
harmonic_num: number of harmonic overtones (default 0)
|
||||
sine_amp: amplitude of sine-wavefrom (default 0.1)
|
||||
noise_std: std of Gaussian noise (default 0.003)
|
||||
voiced_thoreshold: F0 threshold for U/V classification (default 0)
|
||||
flag_for_pulse: this SinGen is used inside PulseGen (default False)
|
||||
Note: when flag_for_pulse is True, the first time step of a voiced
|
||||
segment is always sin(np.pi) or cos(0)
|
||||
"""
|
||||
|
||||
def __init__(self, samp_rate, upsample_scale, harmonic_num=0,
|
||||
sine_amp=0.1, noise_std=0.003,
|
||||
voiced_threshold=0,
|
||||
flag_for_pulse=False):
|
||||
super(SineGen, self).__init__()
|
||||
self.sine_amp = sine_amp
|
||||
self.noise_std = noise_std
|
||||
self.harmonic_num = harmonic_num
|
||||
self.dim = self.harmonic_num + 1
|
||||
self.sampling_rate = samp_rate
|
||||
self.voiced_threshold = voiced_threshold
|
||||
self.flag_for_pulse = flag_for_pulse
|
||||
self.upsample_scale = upsample_scale
|
||||
|
||||
def _f02uv(self, f0):
|
||||
# generate uv signal
|
||||
uv = (f0 > self.voiced_threshold).type(torch.float32)
|
||||
return uv
|
||||
|
||||
def _f02sine(self, f0_values):
|
||||
""" f0_values: (batchsize, length, dim)
|
||||
where dim indicates fundamental tone and overtones
|
||||
"""
|
||||
# convert to F0 in rad. The interger part n can be ignored
|
||||
# because 2 * np.pi * n doesn't affect phase
|
||||
rad_values = (f0_values / self.sampling_rate) % 1
|
||||
|
||||
# initial phase noise (no noise for fundamental component)
|
||||
rand_ini = torch.rand(f0_values.shape[0], f0_values.shape[2], \
|
||||
device=f0_values.device)
|
||||
rand_ini[:, 0] = 0
|
||||
rad_values[:, 0, :] = rad_values[:, 0, :] + rand_ini
|
||||
|
||||
# instantanouse phase sine[t] = sin(2*pi \sum_i=1 ^{t} rad)
|
||||
if not self.flag_for_pulse:
|
||||
# # for normal case
|
||||
|
||||
# # To prevent torch.cumsum numerical overflow,
|
||||
# # it is necessary to add -1 whenever \sum_k=1^n rad_value_k > 1.
|
||||
# # Buffer tmp_over_one_idx indicates the time step to add -1.
|
||||
# # This will not change F0 of sine because (x-1) * 2*pi = x * 2*pi
|
||||
# tmp_over_one = torch.cumsum(rad_values, 1) % 1
|
||||
# tmp_over_one_idx = (padDiff(tmp_over_one)) < 0
|
||||
# cumsum_shift = torch.zeros_like(rad_values)
|
||||
# cumsum_shift[:, 1:, :] = tmp_over_one_idx * -1.0
|
||||
|
||||
# phase = torch.cumsum(rad_values, dim=1) * 2 * np.pi
|
||||
rad_values = torch.nn.functional.interpolate(rad_values.transpose(1, 2),
|
||||
scale_factor=1/self.upsample_scale,
|
||||
mode="linear").transpose(1, 2)
|
||||
|
||||
# tmp_over_one = torch.cumsum(rad_values, 1) % 1
|
||||
# tmp_over_one_idx = (padDiff(tmp_over_one)) < 0
|
||||
# cumsum_shift = torch.zeros_like(rad_values)
|
||||
# cumsum_shift[:, 1:, :] = tmp_over_one_idx * -1.0
|
||||
|
||||
phase = torch.cumsum(rad_values, dim=1) * 2 * np.pi
|
||||
phase = torch.nn.functional.interpolate(phase.transpose(1, 2) * self.upsample_scale,
|
||||
scale_factor=self.upsample_scale, mode="linear").transpose(1, 2)
|
||||
sines = torch.sin(phase)
|
||||
|
||||
else:
|
||||
# If necessary, make sure that the first time step of every
|
||||
# voiced segments is sin(pi) or cos(0)
|
||||
# This is used for pulse-train generation
|
||||
|
||||
# identify the last time step in unvoiced segments
|
||||
uv = self._f02uv(f0_values)
|
||||
uv_1 = torch.roll(uv, shifts=-1, dims=1)
|
||||
uv_1[:, -1, :] = 1
|
||||
u_loc = (uv < 1) * (uv_1 > 0)
|
||||
|
||||
# get the instantanouse phase
|
||||
tmp_cumsum = torch.cumsum(rad_values, dim=1)
|
||||
# different batch needs to be processed differently
|
||||
for idx in range(f0_values.shape[0]):
|
||||
temp_sum = tmp_cumsum[idx, u_loc[idx, :, 0], :]
|
||||
temp_sum[1:, :] = temp_sum[1:, :] - temp_sum[0:-1, :]
|
||||
# stores the accumulation of i.phase within
|
||||
# each voiced segments
|
||||
tmp_cumsum[idx, :, :] = 0
|
||||
tmp_cumsum[idx, u_loc[idx, :, 0], :] = temp_sum
|
||||
|
||||
# rad_values - tmp_cumsum: remove the accumulation of i.phase
|
||||
# within the previous voiced segment.
|
||||
i_phase = torch.cumsum(rad_values - tmp_cumsum, dim=1)
|
||||
|
||||
# get the sines
|
||||
sines = torch.cos(i_phase * 2 * np.pi)
|
||||
return sines
|
||||
|
||||
def forward(self, f0):
|
||||
""" sine_tensor, uv = forward(f0)
|
||||
input F0: tensor(batchsize=1, length, dim=1)
|
||||
f0 for unvoiced steps should be 0
|
||||
output sine_tensor: tensor(batchsize=1, length, dim)
|
||||
output uv: tensor(batchsize=1, length, 1)
|
||||
"""
|
||||
f0_buf = torch.zeros(f0.shape[0], f0.shape[1], self.dim,
|
||||
device=f0.device)
|
||||
# fundamental component
|
||||
fn = torch.multiply(f0, torch.FloatTensor([[range(1, self.harmonic_num + 2)]]).to(f0.device))
|
||||
|
||||
# generate sine waveforms
|
||||
sine_waves = self._f02sine(fn) * self.sine_amp
|
||||
|
||||
# generate uv signal
|
||||
# uv = torch.ones(f0.shape)
|
||||
# uv = uv * (f0 > self.voiced_threshold)
|
||||
uv = self._f02uv(f0)
|
||||
|
||||
# noise: for unvoiced should be similar to sine_amp
|
||||
# std = self.sine_amp/3 -> max value ~ self.sine_amp
|
||||
# . for voiced regions is self.noise_std
|
||||
noise_amp = uv * self.noise_std + (1 - uv) * self.sine_amp / 3
|
||||
noise = noise_amp * torch.randn_like(sine_waves)
|
||||
|
||||
# first: set the unvoiced part to 0 by uv
|
||||
# then: additive noise
|
||||
sine_waves = sine_waves * uv + noise
|
||||
return sine_waves, uv, noise
|
||||
|
||||
|
||||
class SourceModuleHnNSF(torch.nn.Module):
|
||||
""" SourceModule for hn-nsf
|
||||
SourceModule(sampling_rate, harmonic_num=0, sine_amp=0.1,
|
||||
add_noise_std=0.003, voiced_threshod=0)
|
||||
sampling_rate: sampling_rate in Hz
|
||||
harmonic_num: number of harmonic above F0 (default: 0)
|
||||
sine_amp: amplitude of sine source signal (default: 0.1)
|
||||
add_noise_std: std of additive Gaussian noise (default: 0.003)
|
||||
note that amplitude of noise in unvoiced is decided
|
||||
by sine_amp
|
||||
voiced_threshold: threhold to set U/V given F0 (default: 0)
|
||||
Sine_source, noise_source = SourceModuleHnNSF(F0_sampled)
|
||||
F0_sampled (batchsize, length, 1)
|
||||
Sine_source (batchsize, length, 1)
|
||||
noise_source (batchsize, length 1)
|
||||
uv (batchsize, length, 1)
|
||||
"""
|
||||
|
||||
def __init__(self, sampling_rate, upsample_scale, harmonic_num=0, sine_amp=0.1,
|
||||
add_noise_std=0.003, voiced_threshod=0):
|
||||
super(SourceModuleHnNSF, self).__init__()
|
||||
|
||||
self.sine_amp = sine_amp
|
||||
self.noise_std = add_noise_std
|
||||
|
||||
# to produce sine waveforms
|
||||
self.l_sin_gen = SineGen(sampling_rate, upsample_scale, harmonic_num,
|
||||
sine_amp, add_noise_std, voiced_threshod)
|
||||
|
||||
# to merge source harmonics into a single excitation
|
||||
self.l_linear = torch.nn.Linear(harmonic_num + 1, 1)
|
||||
self.l_tanh = torch.nn.Tanh()
|
||||
|
||||
def forward(self, x):
|
||||
"""
|
||||
Sine_source, noise_source = SourceModuleHnNSF(F0_sampled)
|
||||
F0_sampled (batchsize, length, 1)
|
||||
Sine_source (batchsize, length, 1)
|
||||
noise_source (batchsize, length 1)
|
||||
"""
|
||||
# source for harmonic branch
|
||||
with torch.no_grad():
|
||||
sine_wavs, uv, _ = self.l_sin_gen(x)
|
||||
sine_merge = self.l_tanh(self.l_linear(sine_wavs))
|
||||
|
||||
# source for noise branch, in the same shape as uv
|
||||
noise = torch.randn_like(uv) * self.sine_amp / 3
|
||||
return sine_merge, noise, uv
|
||||
def padDiff(x):
|
||||
return F.pad(F.pad(x, (0,0,-1,1), 'constant', 0) - x, (0,0,0,-1), 'constant', 0)
|
||||
|
||||
|
||||
class Generator(torch.nn.Module):
|
||||
def __init__(self, style_dim, resblock_kernel_sizes, upsample_rates, upsample_initial_channel, resblock_dilation_sizes, upsample_kernel_sizes, gen_istft_n_fft, gen_istft_hop_size):
|
||||
super(Generator, self).__init__()
|
||||
|
||||
self.num_kernels = len(resblock_kernel_sizes)
|
||||
self.num_upsamples = len(upsample_rates)
|
||||
resblock = AdaINResBlock1
|
||||
|
||||
self.m_source = SourceModuleHnNSF(
|
||||
sampling_rate=24000,
|
||||
upsample_scale=np.prod(upsample_rates) * gen_istft_hop_size,
|
||||
harmonic_num=8, voiced_threshod=10)
|
||||
self.f0_upsamp = torch.nn.Upsample(scale_factor=np.prod(upsample_rates) * gen_istft_hop_size)
|
||||
self.noise_convs = nn.ModuleList()
|
||||
self.noise_res = nn.ModuleList()
|
||||
|
||||
self.ups = nn.ModuleList()
|
||||
for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)):
|
||||
self.ups.append(weight_norm(
|
||||
ConvTranspose1d(upsample_initial_channel//(2**i), upsample_initial_channel//(2**(i+1)),
|
||||
k, u, padding=(k-u)//2)))
|
||||
|
||||
self.resblocks = nn.ModuleList()
|
||||
for i in range(len(self.ups)):
|
||||
ch = upsample_initial_channel//(2**(i+1))
|
||||
for j, (k, d) in enumerate(zip(resblock_kernel_sizes,resblock_dilation_sizes)):
|
||||
self.resblocks.append(resblock(ch, k, d, style_dim))
|
||||
|
||||
c_cur = upsample_initial_channel // (2 ** (i + 1))
|
||||
|
||||
if i + 1 < len(upsample_rates): #
|
||||
stride_f0 = np.prod(upsample_rates[i + 1:])
|
||||
self.noise_convs.append(Conv1d(
|
||||
gen_istft_n_fft + 2, c_cur, kernel_size=stride_f0 * 2, stride=stride_f0, padding=(stride_f0+1) // 2))
|
||||
self.noise_res.append(resblock(c_cur, 7, [1,3,5], style_dim))
|
||||
else:
|
||||
self.noise_convs.append(Conv1d(gen_istft_n_fft + 2, c_cur, kernel_size=1))
|
||||
self.noise_res.append(resblock(c_cur, 11, [1,3,5], style_dim))
|
||||
|
||||
|
||||
self.post_n_fft = gen_istft_n_fft
|
||||
self.conv_post = weight_norm(Conv1d(ch, self.post_n_fft + 2, 7, 1, padding=3))
|
||||
self.ups.apply(init_weights)
|
||||
self.conv_post.apply(init_weights)
|
||||
self.reflection_pad = torch.nn.ReflectionPad1d((1, 0))
|
||||
self.stft = TorchSTFT(filter_length=gen_istft_n_fft, hop_length=gen_istft_hop_size, win_length=gen_istft_n_fft)
|
||||
|
||||
|
||||
def forward(self, x, s, f0):
|
||||
with torch.no_grad():
|
||||
f0 = self.f0_upsamp(f0[:, None]).transpose(1, 2) # bs,n,t
|
||||
|
||||
har_source, noi_source, uv = self.m_source(f0)
|
||||
har_source = har_source.transpose(1, 2).squeeze(1)
|
||||
har_spec, har_phase = self.stft.transform(har_source)
|
||||
har = torch.cat([har_spec, har_phase], dim=1)
|
||||
|
||||
for i in range(self.num_upsamples):
|
||||
x = F.leaky_relu(x, LRELU_SLOPE)
|
||||
x_source = self.noise_convs[i](har)
|
||||
x_source = self.noise_res[i](x_source, s)
|
||||
|
||||
x = self.ups[i](x)
|
||||
if i == self.num_upsamples - 1:
|
||||
x = self.reflection_pad(x)
|
||||
|
||||
x = x + x_source
|
||||
xs = None
|
||||
for j in range(self.num_kernels):
|
||||
if xs is None:
|
||||
xs = self.resblocks[i*self.num_kernels+j](x, s)
|
||||
else:
|
||||
xs += self.resblocks[i*self.num_kernels+j](x, s)
|
||||
x = xs / self.num_kernels
|
||||
x = F.leaky_relu(x)
|
||||
x = self.conv_post(x)
|
||||
spec = torch.exp(x[:,:self.post_n_fft // 2 + 1, :])
|
||||
phase = torch.sin(x[:, self.post_n_fft // 2 + 1:, :])
|
||||
return self.stft.inverse(spec, phase)
|
||||
|
||||
def fw_phase(self, x, s):
|
||||
for i in range(self.num_upsamples):
|
||||
x = F.leaky_relu(x, LRELU_SLOPE)
|
||||
x = self.ups[i](x)
|
||||
xs = None
|
||||
for j in range(self.num_kernels):
|
||||
if xs is None:
|
||||
xs = self.resblocks[i*self.num_kernels+j](x, s)
|
||||
else:
|
||||
xs += self.resblocks[i*self.num_kernels+j](x, s)
|
||||
x = xs / self.num_kernels
|
||||
x = F.leaky_relu(x)
|
||||
x = self.reflection_pad(x)
|
||||
x = self.conv_post(x)
|
||||
spec = torch.exp(x[:,:self.post_n_fft // 2 + 1, :])
|
||||
phase = torch.sin(x[:, self.post_n_fft // 2 + 1:, :])
|
||||
return spec, phase
|
||||
|
||||
def remove_weight_norm(self):
|
||||
print('Removing weight norm...')
|
||||
for l in self.ups:
|
||||
remove_weight_norm(l)
|
||||
for l in self.resblocks:
|
||||
l.remove_weight_norm()
|
||||
remove_weight_norm(self.conv_pre)
|
||||
remove_weight_norm(self.conv_post)
|
||||
|
||||
|
||||
class AdainResBlk1d(nn.Module):
|
||||
def __init__(self, dim_in, dim_out, style_dim=64, actv=nn.LeakyReLU(0.2),
|
||||
upsample='none', dropout_p=0.0):
|
||||
super().__init__()
|
||||
self.actv = actv
|
||||
self.upsample_type = upsample
|
||||
self.upsample = UpSample1d(upsample)
|
||||
self.learned_sc = dim_in != dim_out
|
||||
self._build_weights(dim_in, dim_out, style_dim)
|
||||
self.dropout = nn.Dropout(dropout_p)
|
||||
|
||||
if upsample == 'none':
|
||||
self.pool = nn.Identity()
|
||||
else:
|
||||
self.pool = weight_norm(nn.ConvTranspose1d(dim_in, dim_in, kernel_size=3, stride=2, groups=dim_in, padding=1, output_padding=1))
|
||||
|
||||
|
||||
def _build_weights(self, dim_in, dim_out, style_dim):
|
||||
self.conv1 = weight_norm(nn.Conv1d(dim_in, dim_out, 3, 1, 1))
|
||||
self.conv2 = weight_norm(nn.Conv1d(dim_out, dim_out, 3, 1, 1))
|
||||
self.norm1 = AdaIN1d(style_dim, dim_in)
|
||||
self.norm2 = AdaIN1d(style_dim, dim_out)
|
||||
if self.learned_sc:
|
||||
self.conv1x1 = weight_norm(nn.Conv1d(dim_in, dim_out, 1, 1, 0, bias=False))
|
||||
|
||||
def _shortcut(self, x):
|
||||
x = self.upsample(x)
|
||||
if self.learned_sc:
|
||||
x = self.conv1x1(x)
|
||||
return x
|
||||
|
||||
def _residual(self, x, s):
|
||||
x = self.norm1(x, s)
|
||||
x = self.actv(x)
|
||||
x = self.pool(x)
|
||||
x = self.conv1(self.dropout(x))
|
||||
x = self.norm2(x, s)
|
||||
x = self.actv(x)
|
||||
x = self.conv2(self.dropout(x))
|
||||
return x
|
||||
|
||||
def forward(self, x, s):
|
||||
out = self._residual(x, s)
|
||||
out = (out + self._shortcut(x)) / math.sqrt(2)
|
||||
return out
|
||||
|
||||
class UpSample1d(nn.Module):
|
||||
def __init__(self, layer_type):
|
||||
super().__init__()
|
||||
self.layer_type = layer_type
|
||||
|
||||
def forward(self, x):
|
||||
if self.layer_type == 'none':
|
||||
return x
|
||||
else:
|
||||
return F.interpolate(x, scale_factor=2, mode='nearest')
|
||||
|
||||
class Decoder(nn.Module):
|
||||
def __init__(self, dim_in=512, F0_channel=512, style_dim=64, dim_out=80,
|
||||
resblock_kernel_sizes = [3,7,11],
|
||||
upsample_rates = [10, 6],
|
||||
upsample_initial_channel=512,
|
||||
resblock_dilation_sizes=[[1,3,5], [1,3,5], [1,3,5]],
|
||||
upsample_kernel_sizes=[20, 12],
|
||||
gen_istft_n_fft=20, gen_istft_hop_size=5):
|
||||
super().__init__()
|
||||
|
||||
self.decode = nn.ModuleList()
|
||||
|
||||
self.encode = AdainResBlk1d(dim_in + 2, 1024, style_dim)
|
||||
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 1024, style_dim))
|
||||
self.decode.append(AdainResBlk1d(1024 + 2 + 64, 512, style_dim, upsample=True))
|
||||
|
||||
self.F0_conv = weight_norm(nn.Conv1d(1, 1, kernel_size=3, stride=2, groups=1, padding=1))
|
||||
|
||||
self.N_conv = weight_norm(nn.Conv1d(1, 1, kernel_size=3, stride=2, groups=1, padding=1))
|
||||
|
||||
self.asr_res = nn.Sequential(
|
||||
weight_norm(nn.Conv1d(512, 64, kernel_size=1)),
|
||||
)
|
||||
|
||||
|
||||
self.generator = Generator(style_dim, resblock_kernel_sizes, upsample_rates,
|
||||
upsample_initial_channel, resblock_dilation_sizes,
|
||||
upsample_kernel_sizes, gen_istft_n_fft, gen_istft_hop_size)
|
||||
|
||||
def forward(self, asr, F0_curve, N, s):
|
||||
if self.training:
|
||||
downlist = [0, 3, 7]
|
||||
F0_down = downlist[random.randint(0, 2)]
|
||||
downlist = [0, 3, 7, 15]
|
||||
N_down = downlist[random.randint(0, 3)]
|
||||
if F0_down:
|
||||
F0_curve = nn.functional.conv1d(F0_curve.unsqueeze(1), torch.ones(1, 1, F0_down).to('cuda'), padding=F0_down//2).squeeze(1) / F0_down
|
||||
if N_down:
|
||||
N = nn.functional.conv1d(N.unsqueeze(1), torch.ones(1, 1, N_down).to('cuda'), padding=N_down//2).squeeze(1) / N_down
|
||||
|
||||
|
||||
F0 = self.F0_conv(F0_curve.unsqueeze(1))
|
||||
N = self.N_conv(N.unsqueeze(1))
|
||||
|
||||
x = torch.cat([asr, F0, N], axis=1)
|
||||
x = self.encode(x, s)
|
||||
|
||||
asr_res = self.asr_res(asr)
|
||||
|
||||
res = True
|
||||
for block in self.decode:
|
||||
if res:
|
||||
x = torch.cat([x, asr_res, F0, N], axis=1)
|
||||
x = block(x, s)
|
||||
if block.upsample_type != "none":
|
||||
res = False
|
||||
|
||||
x = self.generator(x, s, F0_curve)
|
||||
return x
|
||||
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
import torch
|
||||
import numpy as np
|
||||
import torch.nn.functional as F
|
||||
|
||||
class SLMAdversarialLoss(torch.nn.Module):
|
||||
|
||||
def __init__(self, model, wl, sampler, min_len, max_len, batch_percentage=0.5, skip_update=10, sig=1.5):
|
||||
super(SLMAdversarialLoss, self).__init__()
|
||||
self.model = model
|
||||
self.wl = wl
|
||||
self.sampler = sampler
|
||||
|
||||
self.min_len = min_len
|
||||
self.max_len = max_len
|
||||
self.batch_percentage = batch_percentage
|
||||
|
||||
self.sig = sig
|
||||
self.skip_update = skip_update
|
||||
|
||||
def forward(self, iters, y_rec_gt, y_rec_gt_pred, waves, mel_input_length, ref_text, ref_lengths, use_ind, s_trg, ref_s=None):
|
||||
text_mask = length_to_mask(ref_lengths).to(ref_text.device)
|
||||
bert_dur = self.model.bert(ref_text, attention_mask=(~text_mask).int())
|
||||
d_en = self.model.bert_encoder(bert_dur).transpose(-1, -2)
|
||||
|
||||
if use_ind and np.random.rand() < 0.5:
|
||||
s_preds = s_trg
|
||||
else:
|
||||
num_steps = np.random.randint(3, 5)
|
||||
if ref_s is not None:
|
||||
s_preds = self.sampler(noise = torch.randn_like(s_trg).unsqueeze(1).to(ref_text.device),
|
||||
embedding=bert_dur,
|
||||
embedding_scale=1,
|
||||
features=ref_s, # reference from the same speaker as the embedding
|
||||
embedding_mask_proba=0.1,
|
||||
num_steps=num_steps).squeeze(1)
|
||||
else:
|
||||
s_preds = self.sampler(noise = torch.randn_like(s_trg).unsqueeze(1).to(ref_text.device),
|
||||
embedding=bert_dur,
|
||||
embedding_scale=1,
|
||||
embedding_mask_proba=0.1,
|
||||
num_steps=num_steps).squeeze(1)
|
||||
|
||||
s_dur = s_preds[:, 128:]
|
||||
s = s_preds[:, :128]
|
||||
|
||||
d, _ = self.model.predictor(d_en, s_dur,
|
||||
ref_lengths,
|
||||
torch.randn(ref_lengths.shape[0], ref_lengths.max(), 2).to(ref_text.device),
|
||||
text_mask)
|
||||
|
||||
bib = 0
|
||||
|
||||
output_lengths = []
|
||||
attn_preds = []
|
||||
|
||||
# differentiable duration modeling
|
||||
for _s2s_pred, _text_length in zip(d, ref_lengths):
|
||||
|
||||
_s2s_pred_org = _s2s_pred[:_text_length, :]
|
||||
|
||||
_s2s_pred = torch.sigmoid(_s2s_pred_org)
|
||||
_dur_pred = _s2s_pred.sum(axis=-1)
|
||||
|
||||
l = int(torch.round(_s2s_pred.sum()).item())
|
||||
t = torch.arange(0, l).expand(l)
|
||||
|
||||
t = torch.arange(0, l).unsqueeze(0).expand((len(_s2s_pred), l)).to(ref_text.device)
|
||||
loc = torch.cumsum(_dur_pred, dim=0) - _dur_pred / 2
|
||||
|
||||
h = torch.exp(-0.5 * torch.square(t - (l - loc.unsqueeze(-1))) / (self.sig)**2)
|
||||
|
||||
out = torch.nn.functional.conv1d(_s2s_pred_org.unsqueeze(0),
|
||||
h.unsqueeze(1),
|
||||
padding=h.shape[-1] - 1, groups=int(_text_length))[..., :l]
|
||||
attn_preds.append(F.softmax(out.squeeze(), dim=0))
|
||||
|
||||
output_lengths.append(l)
|
||||
|
||||
max_len = max(output_lengths)
|
||||
|
||||
with torch.no_grad():
|
||||
t_en = self.model.text_encoder(ref_text, ref_lengths, text_mask)
|
||||
|
||||
s2s_attn = torch.zeros(len(ref_lengths), int(ref_lengths.max()), max_len).to(ref_text.device)
|
||||
for bib in range(len(output_lengths)):
|
||||
s2s_attn[bib, :ref_lengths[bib], :output_lengths[bib]] = attn_preds[bib]
|
||||
|
||||
asr_pred = t_en @ s2s_attn
|
||||
|
||||
_, p_pred = self.model.predictor(d_en, s_dur,
|
||||
ref_lengths,
|
||||
s2s_attn,
|
||||
text_mask)
|
||||
|
||||
mel_len = max(int(min(output_lengths) / 2 - 1), self.min_len // 2)
|
||||
mel_len = min(mel_len, self.max_len // 2)
|
||||
|
||||
# get clips
|
||||
|
||||
en = []
|
||||
p_en = []
|
||||
sp = []
|
||||
|
||||
F0_fakes = []
|
||||
N_fakes = []
|
||||
|
||||
wav = []
|
||||
|
||||
for bib in range(len(output_lengths)):
|
||||
mel_length_pred = output_lengths[bib]
|
||||
mel_length_gt = int(mel_input_length[bib].item() / 2)
|
||||
if mel_length_gt <= mel_len or mel_length_pred <= mel_len:
|
||||
continue
|
||||
|
||||
sp.append(s_preds[bib])
|
||||
|
||||
random_start = np.random.randint(0, mel_length_pred - mel_len)
|
||||
en.append(asr_pred[bib, :, random_start:random_start+mel_len])
|
||||
p_en.append(p_pred[bib, :, random_start:random_start+mel_len])
|
||||
|
||||
# get ground truth clips
|
||||
random_start = np.random.randint(0, mel_length_gt - mel_len)
|
||||
y = waves[bib][(random_start * 2) * 300:((random_start+mel_len) * 2) * 300]
|
||||
wav.append(torch.from_numpy(y).to(ref_text.device))
|
||||
|
||||
if len(wav) >= self.batch_percentage * len(waves): # prevent OOM due to longer lengths
|
||||
break
|
||||
|
||||
if len(sp) <= 1:
|
||||
return None
|
||||
|
||||
sp = torch.stack(sp)
|
||||
wav = torch.stack(wav).float()
|
||||
en = torch.stack(en)
|
||||
p_en = torch.stack(p_en)
|
||||
|
||||
F0_fake, N_fake = self.model.predictor.F0Ntrain(p_en, sp[:, 128:])
|
||||
y_pred = self.model.decoder(en, F0_fake, N_fake, sp[:, :128])
|
||||
|
||||
# discriminator loss
|
||||
if (iters + 1) % self.skip_update == 0:
|
||||
if np.random.randint(0, 2) == 0:
|
||||
wav = y_rec_gt_pred
|
||||
use_rec = True
|
||||
else:
|
||||
use_rec = False
|
||||
|
||||
crop_size = min(wav.size(-1), y_pred.size(-1))
|
||||
if use_rec: # use reconstructed (shorter lengths), do length invariant regularization
|
||||
if wav.size(-1) > y_pred.size(-1):
|
||||
real_GP = wav[:, : , :crop_size]
|
||||
out_crop = self.wl.discriminator_forward(real_GP.detach().squeeze(0))
|
||||
out_org = self.wl.discriminator_forward(wav.detach().squeeze(0))
|
||||
loss_reg = F.l1_loss(out_crop, out_org[..., :out_crop.size(-1)])
|
||||
|
||||
if np.random.randint(0, 2) == 0:
|
||||
d_loss = self.wl.discriminator(real_GP.detach().squeeze(0), y_pred.detach().squeeze(0)).mean()
|
||||
else:
|
||||
d_loss = self.wl.discriminator(wav.detach().squeeze(0), y_pred.detach().squeeze(0)).mean()
|
||||
else:
|
||||
real_GP = y_pred[:, : , :crop_size]
|
||||
out_crop = self.wl.discriminator_forward(real_GP.detach().squeeze(0))
|
||||
out_org = self.wl.discriminator_forward(y_pred.detach().squeeze(0))
|
||||
loss_reg = F.l1_loss(out_crop, out_org[..., :out_crop.size(-1)])
|
||||
|
||||
if np.random.randint(0, 2) == 0:
|
||||
d_loss = self.wl.discriminator(wav.detach().squeeze(0), real_GP.detach().squeeze(0)).mean()
|
||||
else:
|
||||
d_loss = self.wl.discriminator(wav.detach().squeeze(0), y_pred.detach().squeeze(0)).mean()
|
||||
|
||||
# regularization (ignore length variation)
|
||||
d_loss += loss_reg
|
||||
|
||||
out_gt = self.wl.discriminator_forward(y_rec_gt.detach().squeeze(0))
|
||||
out_rec = self.wl.discriminator_forward(y_rec_gt_pred.detach().squeeze(0))
|
||||
|
||||
# regularization (ignore reconstruction artifacts)
|
||||
d_loss += F.l1_loss(out_gt, out_rec)
|
||||
|
||||
else:
|
||||
d_loss = self.wl.discriminator(wav.detach().squeeze(0), y_pred.detach().squeeze(0)).mean()
|
||||
else:
|
||||
d_loss = 0
|
||||
|
||||
# generator loss
|
||||
gen_loss = self.wl.generator(y_pred.squeeze(0))
|
||||
|
||||
gen_loss = gen_loss.mean()
|
||||
|
||||
return d_loss, gen_loss, y_pred.detach().cpu().numpy()
|
||||
|
||||
def length_to_mask(lengths):
|
||||
mask = torch.arange(lengths.max()).unsqueeze(0).expand(lengths.shape[0], -1).type_as(lengths)
|
||||
mask = torch.gt(mask+1, lengths.unsqueeze(1))
|
||||
return mask
|
||||
@@ -0,0 +1,14 @@
|
||||
def init_weights(m, mean=0.0, std=0.01):
|
||||
classname = m.__class__.__name__
|
||||
if classname.find("Conv") != -1:
|
||||
m.weight.data.normal_(mean, std)
|
||||
|
||||
|
||||
def apply_weight_norm(m):
|
||||
classname = m.__class__.__name__
|
||||
if classname.find("Conv") != -1:
|
||||
weight_norm(m)
|
||||
|
||||
|
||||
def get_padding(kernel_size, dilation=1):
|
||||
return int((kernel_size*dilation - dilation)/2)
|
||||
@@ -0,0 +1,132 @@
|
||||
# StyleTTS 2: Towards Human-Level Text-to-Speech through Style Diffusion and Adversarial Training with Large Speech Language Models
|
||||
|
||||
# This is a snapshot:
|
||||
d0ea889aa827b0c87e50ca44b302b030ccaf95e2
|
||||
https://dagshub.com/StyleTTS/StyleTTS2/commits/main
|
||||
|
||||
To run:
|
||||
accelerate launch --mixed_precision=fp16 --num_processes=1 train_finetune_accelerate.py --config_path ./Configs/config_harness.yml # use your own config but ensure you use train_finetune_accelerate.py
|
||||
|
||||
Should be accessible in our weights and biases account.
|
||||
With a test harness that will be able easily observe the results to weights and biases.
|
||||
Use python 3.10.12
|
||||
|
||||
https://github.com/yl4579/StyleTTS2/discussions/81
|
||||
|
||||
### Yinghao Aaron Li, Cong Han, Vinay S. Raghavan, Gavin Mischler, Nima Mesgarani
|
||||
|
||||
> In this paper, we present StyleTTS 2, a text-to-speech (TTS) model that leverages style diffusion and adversarial training with large speech language models (SLMs) to achieve human-level TTS synthesis. StyleTTS 2 differs from its predecessor by modeling styles as a latent random variable through diffusion models to generate the most suitable style for the text without requiring reference speech, achieving efficient latent diffusion while benefiting from the diverse speech synthesis offered by diffusion models. Furthermore, we employ large pre-trained SLMs, such as WavLM, as discriminators with our novel differentiable duration modeling for end-to-end training, resulting in improved speech naturalness. StyleTTS 2 surpasses human recordings on the single-speaker LJSpeech dataset and matches it on the multispeaker VCTK dataset as judged by native English speakers. Moreover, when trained on the LibriTTS dataset, our model outperforms previous publicly available models for zero-shot speaker adaptation. This work achieves the first human-level TTS synthesis on both single and multispeaker datasets, showcasing the potential of style diffusion and adversarial training with large SLMs.
|
||||
|
||||
Paper: [https://arxiv.org/abs/2306.07691](https://arxiv.org/abs/2306.07691)
|
||||
|
||||
Audio samples: [https://styletts2.github.io/](https://styletts2.github.io/)
|
||||
|
||||
Online demo: [Hugging Face](https://huggingface.co/spaces/styletts2/styletts2) (thank [@fakerybakery](https://github.com/fakerybakery) for the wonderful online demo)
|
||||
|
||||
[](https://colab.research.google.com/github/yl4579/StyleTTS2/blob/main/) [](https://join.slack.com/t/styletts2/shared_invite/zt-2805io6cg-0ROMhjfW9Gd_ix_FJqjGmQ)
|
||||
|
||||
## TODO
|
||||
- [x] Training and inference demo code for single-speaker models (LJSpeech)
|
||||
- [x] Test training code for multi-speaker models (VCTK and LibriTTS)
|
||||
- [x] Finish demo code for multispeaker model and upload pre-trained models
|
||||
- [x] Add a finetuning script for new speakers with base pre-trained multispeaker models
|
||||
- [ ] Fix DDP (accelerator) for `train_second.py` **(I have tried everything I could to fix this but had no success, so if you are willing to help, please see [#7](https://github.com/yl4579/StyleTTS2/issues/7))**
|
||||
|
||||
## Pre-requisites
|
||||
1. Python >= 3.7
|
||||
2. Clone this repository:
|
||||
```bash
|
||||
git clone https://github.com/yl4579/StyleTTS2.git
|
||||
cd StyleTTS2
|
||||
```
|
||||
3. Install python requirements:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
On Windows add:
|
||||
```bash
|
||||
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 -U
|
||||
```
|
||||
Also install phonemizer and espeak if you want to run the demo:
|
||||
```bash
|
||||
pip install phonemizer
|
||||
sudo apt-get install espeak-ng
|
||||
```
|
||||
4. Download and extract the [LJSpeech dataset](https://keithito.com/LJ-Speech-Dataset/), unzip to the data folder and upsample the data to 24 kHz. The text aligner and pitch extractor are pre-trained on 24 kHz data, but you can easily change the preprocessing and re-train them using your own preprocessing.
|
||||
For LibriTTS, you will need to combine train-clean-360 with train-clean-100 and rename the folder train-clean-460 (see [val_list_libritts.txt](https://github.com/yl4579/StyleTTS/blob/main/Data/val_list_libritts.txt) as an example).
|
||||
|
||||
## Training
|
||||
First stage training:
|
||||
```bash
|
||||
accelerate launch train_first.py --config_path ./Configs/config.yml
|
||||
```
|
||||
Second stage training **(DDP version not working, so the current version uses DP, again see [#7](https://github.com/yl4579/StyleTTS2/issues/7) if you want to help)**:
|
||||
```bash
|
||||
python train_second.py --config_path ./Configs/config.yml
|
||||
```
|
||||
You can run both consecutively and it will train both the first and second stages. The model will be saved in the format "epoch_1st_%05d.pth" and "epoch_2nd_%05d.pth". Checkpoints and Tensorboard logs will be saved at `log_dir`.
|
||||
|
||||
The data list format needs to be `filename.wav|transcription|speaker`, see [val_list.txt](https://github.com/yl4579/StyleTTS2/blob/main/Data/val_list.txt) as an example. The speaker labels are needed for multi-speaker models because we need to sample reference audio for style diffusion model training.
|
||||
|
||||
### Important Configurations
|
||||
In [config.yml](https://github.com/yl4579/StyleTTS2/blob/main/Configs/config.yml), there are a few important configurations to take care of:
|
||||
- `OOD_data`: The path for out-of-distribution texts for SLM adversarial training. The format should be `text|anything`.
|
||||
- `min_length`: Minimum length of OOD texts for training. This is to make sure the synthesized speech has a minimum length.
|
||||
- `max_len`: Maximum length of audio for training. The unit is frame. Since the default hop size is 300, one frame is approximately `300 / 24000` (0.0125) second. Lowering this if you encounter the out-of-memory issue.
|
||||
- `multispeaker`: Set to true if you want to train a multispeaker model. This is needed because the architecture of the denoiser is different for single and multispeaker models.
|
||||
- `batch_percentage`: This is to make sure during SLM adversarial training there are no out-of-memory (OOM) issues. If you encounter OOM problem, please set a lower number for this.
|
||||
|
||||
### Pre-trained modules
|
||||
In [Utils](https://github.com/yl4579/StyleTTS2/tree/main/Utils) folder, there are three pre-trained models:
|
||||
- **[ASR](https://github.com/yl4579/StyleTTS2/tree/main/Utils/ASR) folder**: It contains the pre-trained text aligner, which was pre-trained on English (LibriTTS), Japanese (JVS), and Chinese (AiShell) corpus. It works well for most other languages without fine-tuning, but you can always train your own text aligner with the code here: [yl4579/AuxiliaryASR](https://github.com/yl4579/AuxiliaryASR).
|
||||
- **[JDC](https://github.com/yl4579/StyleTTS2/tree/main/Utils/JDC) folder**: It contains the pre-trained pitch extractor, which was pre-trained on English (LibriTTS) corpus only. However, it works well for other languages too because F0 is independent of language. If you want to train on singing corpus, it is recommended to train a new pitch extractor with the code here: [yl4579/PitchExtractor](https://github.com/yl4579/PitchExtractor).
|
||||
- **[PLBERT](https://github.com/yl4579/StyleTTS2/tree/main/Utils/PLBERT) folder**: It contains the pre-trained [PL-BERT](https://arxiv.org/abs/2301.08810) model, which was pre-trained on English (Wikipedia) corpus only. It probably does not work very well on other languages, so you will need to train a different PL-BERT for different languages using the repo here: [yl4579/PL-BERT](https://github.com/yl4579/PL-BERT). You can also replace this module with other phoneme BERT models like [XPhoneBERT](https://arxiv.org/abs/2305.19709) which is pre-trained on more than 100 languages.
|
||||
|
||||
### Common Issues
|
||||
- **Loss becomes NaN**: If it is the first stage, please make sure you do not use mixed precision, as it can cause loss becoming NaN for some particular datasets when the batch size is not set properly (need to be more than 16 to work well). For the second stage, please also experiment with different batch sizes, with higher batch sizes being more likely to cause NaN loss values. We recommend the batch size to be 16. You can refer to issues [#10](https://github.com/yl4579/StyleTTS2/issues/10) and [#11](https://github.com/yl4579/StyleTTS2/issues/11) for more details.
|
||||
- **Out of memory**: Please either use lower `batch_size` or `max_len`. You may refer to issue [#10](https://github.com/yl4579/StyleTTS2/issues/10) for more information.
|
||||
- **Non-English dataset**: You can train on any language you want, but the current bottleneck is PL-BERT. The pre-trained PL-BERT in English would still work for other languages, but it will not be as good as English (you may refer to [yl4579/StyleTTS#10](https://github.com/yl4579/StyleTTS/issues/10) and [#70](https://github.com/yl4579/StyleTTS2/issues/70) for some examples to train on Chinese datasets). We are currently planning on training multi-lingual PL-BERT models for the best performance. You can go to [#41](https://github.com/yl4579/StyleTTS2/issues/41) if you would like to help.
|
||||
|
||||
## Finetuning
|
||||
The script is modified from `train_second.py` which uses DP, as DDP does not work for `train_second.py`. Please see the bold section above if you are willing to help with this problem.
|
||||
```bash
|
||||
python train_finetune.py --config_path ./Configs/config_ft.yml
|
||||
```
|
||||
Please make sure you have the LibriTTS checkpoint downloaded and unzipped under the folder. The default configuration `config_ft.yml` finetunes on LJSpeech with 1 hour of speech data (around 1k samples) for 50 epochs. This took about 4 hours to finish on four NVidia A100. The quality is slightly worse (similar to NaturalSpeech on LJSpeech) than LJSpeech model trained from scratch with 24 hours of speech data, which took around 2.5 days to finish on four A100. The samples can be found at [#65 (comment)](https://github.com/yl4579/StyleTTS2/discussions/65#discussioncomment-7668393).
|
||||
|
||||
If you are using a **single GPU** (because the script doesn't work with DDP) and want to save training speed and VRAM, you can do (thank [@korakoe](https://github.com/korakoe) for making the script at [#100](https://github.com/yl4579/StyleTTS2/pull/100)):
|
||||
```bash
|
||||
accelerate launch --mixed_precision=fp16 --num_processes=1 train_finetune_accelerate.py --config_path ./Configs/config_ft.yml
|
||||
```
|
||||
[](https://colab.research.google.com/github/yl4579/StyleTTS2/blob/main/Colab/StyleTTS2_Finetune_Demo.ipynb)
|
||||
|
||||
### Common Issues
|
||||
[@Kreevoz](https://github.com/Kreevoz) has made detailed notes on common issues in finetuning, with suggestions in maximizing audio quality: [#81](https://github.com/yl4579/StyleTTS2/discussions/81). Some of these also apply to training from scratch. [@IIEleven11](https://github.com/IIEleven11) has also made a guideline for fine-tuning: [#128](https://github.com/yl4579/StyleTTS2/discussions/128).
|
||||
|
||||
- **Out of memory after `joint_epoch`**: This is likely because your GPU RAM is not big enough for SLM adversarial training run. You may skip that but the quality could be worse. Setting `joint_epoch` a larger number than `epochs` could skip the SLM advesariral training.
|
||||
|
||||
## Inference
|
||||
Please refer to [Inference_LJSpeech.ipynb](https://github.com/yl4579/StyleTTS2/blob/main/Demo/Inference_LJSpeech.ipynb) (single-speaker) and [Inference_LibriTTS.ipynb](https://github.com/yl4579/StyleTTS2/blob/main/Demo/Inference_LibriTTS.ipynb) (multi-speaker) for details. For LibriTTS, you will also need to download [reference_audio.zip](https://huggingface.co/yl4579/StyleTTS2-LibriTTS/resolve/main/reference_audio.zip) and unzip it under the `demo` before running the demo.
|
||||
|
||||
- The pretrained StyleTTS 2 on LJSpeech corpus in 24 kHz can be downloaded at [https://huggingface.co/yl4579/StyleTTS2-LJSpeech/tree/main](https://huggingface.co/yl4579/StyleTTS2-LJSpeech/tree/main).
|
||||
|
||||
[](https://colab.research.google.com/github/yl4579/StyleTTS2/blob/main/Colab/StyleTTS2_Demo_LJSpeech.ipynb)
|
||||
|
||||
- The pretrained StyleTTS 2 model on LibriTTS can be downloaded at [https://huggingface.co/yl4579/StyleTTS2-LibriTTS/tree/main](https://huggingface.co/yl4579/StyleTTS2-LibriTTS/tree/main).
|
||||
|
||||
[](https://colab.research.google.com/github/yl4579/StyleTTS2/blob/main/Colab/StyleTTS2_Demo_LibriTTS.ipynb)
|
||||
|
||||
|
||||
You can import StyleTTS 2 and run it in your own code. However, the inference depends on a GPL-licensed package, so it is not included directly in this repository. A [GPL-licensed fork](https://github.com/NeuralVox/StyleTTS2) has an importable script, as well as an experimental streaming API, etc. A [fully MIT-licensed package](https://pypi.org/project/styletts2/) that uses gruut (albeit lower quality due to mismatch between phonemizer and gruut) is also available.
|
||||
|
||||
***Before using these pre-trained models, you agree to inform the listeners that the speech samples are synthesized by the pre-trained models, unless you have the permission to use the voice you synthesize. That is, you agree to only use voices whose speakers grant the permission to have their voice cloned, either directly or by license before making synthesized voices public, or you have to publicly announce that these voices are synthesized if you do not have the permission to use these voices.***
|
||||
|
||||
### Common Issues
|
||||
- **High-pitched background noise**: This is caused by numerical float differences in older GPUs. For more details, please refer to issue [#13](https://github.com/yl4579/StyleTTS2/issues/13). Basically, you will need to use more modern GPUs or do inference on CPUs.
|
||||
- **Pre-trained model license**: You only need to abide by the above rules if you use **the pre-trained models** and the voices are **NOT** in the training set, i.e., your reference speakers are not from any open access dataset. For more details of rules to use the pre-trained models, please see [#37](https://github.com/yl4579/StyleTTS2/issues/37).
|
||||
|
||||
## References
|
||||
- [archinetai/audio-diffusion-pytorch](https://github.com/archinetai/audio-diffusion-pytorch)
|
||||
- [jik876/hifi-gan](https://github.com/jik876/hifi-gan)
|
||||
- [rishikksh20/iSTFTNet-pytorch](https://github.com/rishikksh20/iSTFTNet-pytorch)
|
||||
- [nii-yamagishilab/project-NN-Pytorch-scripts/project/01-nsf](https://github.com/nii-yamagishilab/project-NN-Pytorch-scripts/tree/master/project/01-nsf)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
wavs/27.wav|I will catch up! It's game over, Yugi! I completely obliterated you!
|
||||
wavs/71.wav|But that's the last move you'll ever make! I activate my trap! I activate my spell card! Raigeki! Change of Heart!
|
||||
wavs/115.wav|Combine into one! X Y Zee Dragon Cannon! X Y Zee Dragon Cannons effect activates!
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,109 @@
|
||||
wavs/1.wav|Don't you realize it's your bedtime? Staying up late is bad for your skin, and it makes you irritable, and it ruins your appetite. I won't allow it!
|
||||
wavs/2.wav|Now get to bed this instant!
|
||||
wavs/4.wav|All of the Pokemon are better, but this one's still holding its head! Then maybe you can help it!
|
||||
wavs/5.wav|Do you kids have any idea just what time it is? Don't you know that you should be sleeping now? I'm sorry, but there's something really wrong with my Pikachu!
|
||||
wavs/6.wav|There's no need to get excited, look! Sparks are coming from its cheeks, right? That's an early symptom of a cold in Electric Rodent Pokemon.
|
||||
wavs/7.wav|If you leave it here overnight, I'm sure it'll be fine in the morning. Oh, no. It's all my other relatives that are odd. They're in intensive care.
|
||||
wavs/8.wav|If we don't get the power back soon, well I just don't want to think about what would happen. I don't know what to do.
|
||||
wavs/9.wav|You worked so hard to make sure all these Pokemon survived, you've inspired me to become a better nurse.
|
||||
wavs/10.wav|We will, and please come back and visit us. Bye! Have you ever heard of the mysterious garden?
|
||||
wavs/11.wav|Yes, it's perfect for people whose age or health keeps them from traveling around, and it's also nice for people like me who can't ever seem to get away from work!
|
||||
wavs/12.wav|They already left! They're on their way to the next gym! What's wrong with that Meowth? Yeah, I'm sorry.
|
||||
wavs/13.wav|I couldn't help but overhear you talking. Are you Professor Oak and D J Mary? Then who's over there having breakfast?
|
||||
wavs/14.wav|Guess after all the game shows I've watched, I can probably fake it. Right. Here is the first question. What is the evolved form of Slowpoke?
|
||||
wavs/15.wav|Sorry, there was more to the question. You were correct in saying Slowpoke evolves into Slowbro, but.
|
||||
wavs/16.wav|But what is the name of the psychic attack that Slowbro learns upon reaching level forty six? The answer is Aipom's Tail. Professor A is correct.
|
||||
wavs/17.wav|That's right, Professor B is correct. The attack is amnesia. This question deals with a silhouette. Examine this silhouette and tell me which Pokemon it is.
|
||||
wavs/18.wav|Fine! Wobbuffet will be the theme of our two poems. Contestant A is the one and only true Professor Oak.
|
||||
wavs/19.wav|Not true! Your work showed no understanding of Pokemon poetry! I oughta know since I'm a fifth level master of Pokemon poetry!
|
||||
wavs/20.wav|All of Professor Oak's poems have one thing in common, the ability to reassure and relax people.
|
||||
wavs/21.wav|Such as, Blastoise fight or hide away to fight again some other day. Obviously, one meaning is literally to be careful.
|
||||
wavs/22.wav|But the deeper message is for all people to save their strength for those difficult times in life when they will really need it.
|
||||
wavs/23.wav|And to give another example, Sandslash rolls into a spiny ball, three meals a day, and eats them all!
|
||||
wavs/24.wav|On the surface, this poem sounds like just a description of Sandslash and its lifestyle, but it also carries a lesson for us. Oh no! The catered lunch!
|
||||
wavs/25.wav|I'm sure you'll treat it very well. Goodbye! Take care now! We'd also like to find out if there's any truth to the claims about Kabuto oil.
|
||||
wavs/26.wav|One of the main reasons we've come here is to learn everything we can about the habitat of the extinct Pokemon, Kabuto.
|
||||
wavs/27.wav|Well, legend has it that the oil from Kabuto shells not only brings good health, but it can make people live forever.
|
||||
wavs/28.wav|Of course we know that's impossible, but there could be some basis to the legend, and kabuto oil may prove to be of great historic importance to medical science.
|
||||
wavs/29.wav|Rhydon! Horn drill that rock now! Chansey, would you take Scyther to recovery?
|
||||
wavs/30.wav|All I can say is that I'm so very sorry that I didn't believe the prophecy and the warnings you gave us.
|
||||
wavs/31.wav|Scyther is still very weak. It's going to take a few days to get its strength back. You've got to relax or you won't heal properly, Scyther.
|
||||
wavs/32.wav|I guess the old warrior finally lost a battle for leadership of its swarm. Excuse me, but what's going on here?
|
||||
wavs/33.wav|Well, an older Scyther only could have gotten these kinds of injuries by battling another Scyther.
|
||||
wavs/34.wav|Usually it's a younger, faster Scyther that challenges the leader. Sometimes speed and power can overcome even the most experienced Pokemon.
|
||||
wavs/35.wav|Once a leader's defeated by another Scyther, it can't stay with the swarm. Unless it wins a new leadership battle, it has to live all by itself.
|
||||
wavs/36.wav|Well, when was the last time your Snorlax ate? Well, that's why it won't wake up. Snorlax won't be battling tomorrow.
|
||||
wavs/37.wav|Unless there's danger, it won't wake up until it's hungry again, and that could take days.
|
||||
wavs/38.wav|Well, maybe if you got out of this lab once in a while, you'd start to notice what's going on around you. Now what are you going to tell that new trainer when she comes here to pick up her Totodile?
|
||||
wavs/39.wav|Stop making excuses for yourself, Professor! Could someone tell me what's going on here? Well, I'm afraid someone has stolen a Pokemon!
|
||||
wavs/40.wav|A new trainer's very first Pokemon is gone! That poor girl! That poor Totodile! I know that sometimes Professor Elm may sound like a hothead.
|
||||
wavs/41.wav|But he's really very sweet, and he raises wonderful Pokemon. Oh, I'm so sorry, I was supposed to be back at the Pokemon Center by two, but when I got to the lab, I lost track of time.
|
||||
wavs/42.wav|Where did Professor Elm go? He'll be a while. In the meantime, let's do what you came here to do and get you registered and approved for the Johto League!
|
||||
wavs/43.wav|Congratulations, Ash! You're now fully qualified and approved to become an official participant in the Johto League. I just hope you can understand that Blissey only wants to help.
|
||||
wavs/44.wav|You'll need a copy of the Johto League Guidebook, so make sure you don't lose it! Once he earns eight badges, he'll be qualified to enter and participate in the Johto Championship.
|
||||
wavs/45.wav|I'd say the best place to start is the Violet Gym in Violet City. I can't tell you how sorry I am for all the trouble my Blissey has caused for you, Ash.
|
||||
wavs/46.wav|I know how you must feel, but Blissey's heart's always in the right place. Anyway, I just want you to know that Blissey always tries very hard to be the best nurse it can be.
|
||||
wavs/47.wav|Isn't that right? What's wrong? I don't believe it! The pantry was full just yesterday! Let's go to security!
|
||||
wavs/48.wav|Maybe the camera can tell us who. Looks like our thief is Blissey. I can't believe you were behind this. What did you do with all that food?
|
||||
wavs/49.wav|Blissey, if you tell me where the food is, maybe I can keep you out of trouble. Blissey, listen to me, this could end your career as a Pokemon nurse.
|
||||
wavs/50.wav|They must be the ones who made Blissey steal all of the food! I'm sorry. Blissey, please forgive me for doubting you even for a minute.
|
||||
wavs/51.wav|Does that Chikorita belong to you? And what's your name? Correct! And I have a degree in Pokemon Psychology from Celadon University.
|
||||
wavs/52.wav|I provide innovative counseling techniques and new Pokemon therapy. I'm sorry, but I'm afraid I only deal with Pokemon.
|
||||
wavs/53.wav|I have an idea, Ash. Why don't you and your Pokemon join me and we'll have a counseling session. Interesting. I think I know the problem.
|
||||
wavs/54.wav|Maybe, but I'm going to need your help to explore the issues that may be causing your Chikorita's behavior. Chikorita was suffering from envy.
|
||||
wavs/55.wav|You say Chikorita's refusal to return occurred while you were battling another trainer and his Raticate earlier this evening?
|
||||
wavs/56.wav|You wanted to substitute Pikachu just when Chikorita thought it was on the verge of winning a battle for you. Don't worry, Ash. I think we can work through it.
|
||||
wavs/57.wav|So it's understandable that Chikorita feels that you trust and care more for Pikachu and it's jealous. Chikorita is a Grass type Pokemon.
|
||||
wavs/58.wav|Why don't you try to get Chikorita to return to its Pokeball now? Yes, I do. The new Pokemon therapies are quite effective.
|
||||
wavs/59.wav|But I think it's best if your Chikorita stays here in the greenhouse tonight. Yep, this is a textbook case.
|
||||
wavs/60.wav|That Chikorita craves your attention, and an excellent way to get it is by running away. I think you'd better hurry, Ash.
|
||||
wavs/61.wav|This is a pretty tough neighborhood, and it's got some pretty rough Pokemon. Thanks, Ash. I'm glad I could help out. I just wish I had time to explore Chikorita's psyche.
|
||||
wavs/62.wav|I'm glad that's over with. You saw through my suit? And who might you be? Hello, how are you, Pikachu? Would you like to come for treatment in my Pokemon Center?
|
||||
wavs/63.wav|I was talking to Pikachu, but you can all come along if you'd like. Yes, but I didn't write that book, Brock. My grandmother did. It was about fifty years ago.
|
||||
wavs/64.wav|In those days, the lake and this whole area were terribly polluted by the waste from nearby factories and towns. It was so bad even the Muk stayed away.
|
||||
wavs/65.wav|But grandmother still loved this place, so she decided to do something. She dedicated her life to studying the effects of pollution on Pokemon.
|
||||
wavs/66.wav|And she told the world about what she learned in a spring without Pokemon. I could sign my name, but it wouldn't be authentic if it's not from my grandmother.
|
||||
wavs/67.wav|I'm sorry, but I didn't write that book either, Brock. My mother was inspired by my grandmother's work, so she decided to carry it further, after a lot of work.
|
||||
wavs/68.wav|She managed to get the factories and towns to stop polluting the lake. Then she was put in charge of draining the toxic water, cleaning the lake bed, and refilling it.
|
||||
wavs/69.wav|The Grimer and Muk returned first, but my mother kept working. Soon the lake was crystal clear and water Pokemon came here to live again.
|
||||
wavs/70.wav|So many came that she decided to build the Lake Lucid Pokemon Center to take care of them, and now I'm here trying to carry on the family tradition.
|
||||
wavs/71.wav|We specialize in water Pokemon, and they love to come here for our personalized treatments and because the lake is so clean. I haven't written a book yet Brock.
|
||||
wavs/72.wav|Oh, they're not really battling each other. They're all just trying to get back into shape by practicing. Following in my grandmother's and my mother's footsteps, of course.
|
||||
wavs/73.wav|We've all worked very hard to make the Lake Lucid Center a success. It's to honor my mom and my grandmother.
|
||||
wavs/74.wav|But I'm planning to write one soon, and I think I'm gonna call it An Autumn Harvest of Pokemon. That oughta do the trick. Of course. I'd be very happy to.
|
||||
wavs/75.wav|The lake's a place where the Water Pokemon can exercise and build up their strength physically and emotionally. Wait a minute, did you say they're Water Pokemon?
|
||||
wavs/76.wav|Keep it away! Whatever you do, don't let those water Pokemon out of those Pokeballs! Don't let them near me, don't let them touch me! And whatever you do, please keep them away from me!
|
||||
wavs/77.wav|I'm sorry, maybe I should have mentioned this before, but I... I hate those Pokemon! Sorry, please keep those things away from me!
|
||||
wavs/78.wav|I absolutely can't stand the sight of those Pokemon! I can handle Electric Pokemon, Poison Pokemon, I even love Bug Pokemon! Just as long as I don't have to touch them!
|
||||
wavs/79.wav|Any kind of Pokemon except those awful, horrible, terrible water Pokemon! I wouldn't even touch a water Pokemon, wearing this special protective suit!
|
||||
wavs/80.wav|I don't dislike them! I hate them! I really wish you wouldn't feel that way, Misty. I'm very happy to treat every kind of water Pokemon who comes to the center.
|
||||
wavs/81.wav|Don't be ridiculous! We provide the best water Pokemon care anywhere. Doesn't yours deserve the best?
|
||||
wavs/82.wav|I hope you're not assuming that my personal preferences affect my job performance because I can assure you that they don't. I treat all patients equally.
|
||||
wavs/83.wav|Thanks, Misty. I was hoping you'd say that. It's a little tough to handle those things with these things. You did a great job with those bandages, Chansey.
|
||||
wavs/84.wav|Excellent as always.
|
||||
wavs/85.wav|Thanks to my three assistants, I can treat water Pokemon without ever having to lay a hand on them.
|
||||
wavs/86.wav|Water Pokemon can get many different kinds of injuries and illnesses, so over the years we've developed a number of different kinds of healing water baths to treat them with.
|
||||
wavs/87.wav|Everybody has a certain Pokemon they like and a certain Pokemon they don't like, and when it comes to Gyarados, no way Jose!
|
||||
wavs/88.wav|Gyarados have such large, heavy heads that it's quite common for them to experience neck and back problems. That's right. Why? What do you mean?
|
||||
wavs/89.wav|I've studied all kinds of water Pokemon, and I've created special treatments, special diets, even special exercises that help each one overcome their illnesses and injuries.
|
||||
wavs/90.wav|I understand water Pokemon, and I'm going to write a book so others can understand them, too. I never allow my feelings to interfere with my work!
|
||||
wavs/91.wav|I'm a Pokemon nurse. I don't have to cuddle my patients to learn what I have to about them, but I do the best job I can to honor both of them.
|
||||
wavs/92.wav|I did! I grew up and continued the work my mother and grandmother started. I may never be as great as they were.
|
||||
wavs/93.wav|I don't hate my job, Misty. I love Lake Lucid, and I'm able to treat all kinds of sick and injured Pokemon, and that's what makes me happy.
|
||||
wavs/94.wav|Unfortunately for me, there are always all kinds of water Pokemon. But a Pokemon nurse does what she has to. It's a fake! A fake Tentacruel!
|
||||
wavs/95.wav|What's going on here? We have to do something before it injures itself even more! Gyarados is my responsibility!
|
||||
wavs/96.wav|Neither of you has ever tried to calm a Gyarados in pain. You may be great Pokemon trainers, but neither of you is a trained nurse. All right, Chansey, let's get ready. Bring in the brace.
|
||||
wavs/97.wav|That's why I have to be the one to deal with that Gyarados, and so I will. This is an emergency, and nurses don't get to pick and choose their patients.
|
||||
wavs/98.wav|It's a nurse's duty to heal the sick, whoever they may be. I can't focus on how I feel about water Pokemon.
|
||||
wavs/99.wav|But if I can just stay focused on the fact that I'm a nurse like my grandmother and my mother. I have to help this poor Gyarados!
|
||||
wavs/100.wav|And no matter what my feelings are, I have a duty to help and heal all Pokemon. I can do this! If I touch it the right way, it'll calm down.
|
||||
wavs/101.wav|Put it on, Chansey! There's no Pokemon that's better than any other. There's no Pokemon that's worse than any other. They're all precious creatures!
|
||||
wavs/102.wav|The song of every Pokemon is sweet if you can hear it! You'll be just fine. You all did a wonderful job. Now take this Gyarados to another water tank, please.
|
||||
wavs/103.wav|Well, Misty, I'd still like to give your Water Pokemon a full examination.
|
||||
wavs/104.wav|Maybe. I'm sorry Misty, I wasn't able to touch your water Pokemon.
|
||||
wavs/105.wavAall of them are in top physical condition. They have an excellent trainer. Yes, Misty. I still do and will for the rest of my life.
|
||||
wavs/106.wav|But that won't stop me! I have a job to do, and a Pokemon Center to run, and a book to write!
|
||||
wavs/107.wav|I'm sure I just closed that. It's okay! You don't need to fight with him, Shiftry! Yeah.
|
||||
wavs/108.wav|Shiftry, you're a good friend to Nuzleaf. Nuzleaf is gonna be just fine. Thank you for all of your help.
|
||||
wavs/109.wav|I'll take care of everything, but I don't have some of the supplies I need with me. Everything's okay now, Shiftry.
|
||||
wavs/110.wav|We've done everything we can to keep Nuzleaf comfortable, but I need to get some of my medicines! So I have to go back to the Pokemon Center and get them!
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,377 @@
|
||||
wavs/1.wav|It isn't supposed to be me. Padme stands in her office, waiting to stride into the Galactic Senate chamber.
|
||||
wavs/10.wav|Just days before, it had seemed as if there might be hope, for the first time in so long. The Senate had convened an emergency session to discuss the disaster the war had become.
|
||||
wavs/100.wav|and suddenly a giant hologram of Count Dooku appeared in the Senate chamber. Padme reflexively stiffened, he intoned. The news hit Padme like a slap.
|
||||
wavs/101.wav|No. It couldn't be. There were cries around her. Other senators cheered. But Padme could barely hear them. Mina was dead.
|
||||
wavs/102.wav|In the hallway outside the Senate chamber, Bail and Padme met. Padme's hand maiden, Tecla, at her side. Padme could barely speak.
|
||||
wavs/103.wav|Everything had gone so terribly wrong, and now Mina was dead, and Republic forces had done it? I can't believe it, she said.
|
||||
wavs/104.wav|Bail put his hand on her shoulder. Padme stopped. Of course. Dooku had killed her. He didn't want democracy. He didn't want peace.
|
||||
wavs/105.wav|He let the Confederate Senate have its vote and then killed the senator who'd sponsored it. He did control the universe.
|
||||
wavs/106.wav|Mina had been wrong, and it had killed her. What can we do? Padme asked, for once. She could see no way out.
|
||||
wavs/107.wav|Bail proceeded to answer as if she was asking a practical question, but Tecla understood the helplessness underneath it. She touched Padme's elbow gently.
|
||||
wavs/108.wav|Bail had a plan. Gather the information on the real cost of Bertone's proposal and try to talk sense into the other Senators before the vote.
|
||||
wavs/109.wav|Fine. Padme would try. She went to the Banking Clan to find out exactly what these five million troops would cost. Free from regulation.
|
||||
wavs/11.wav|And the fix on the table was the same fix as always, more troops. As if more troops had done anything thus far, the Republic ordered more clones.
|
||||
wavs/110.wav|The banks had raised the interest rate from ten percent to twenty five. For every hundred credits borrowed, they'd owe a hundred twenty five.
|
||||
wavs/111.wav|and that amount would only grow the longer it took to pay it back. Already social services were being cut everywhere. Education. Health care.
|
||||
wavs/112.wav|infrastructure. And that meant people were suffering. If they passed the bill, they wouldn't even be able to meet people's basic needs.
|
||||
wavs/113.wav|The bill would essentially destroy the republic. The separatists could just sit back and watch. To make matters worse, senators had started to receive threats.
|
||||
wavs/114.wav|Senator Farr had been jumped by two bounty hunters in the night, and his arm was in a sling. The Viking clan would stop at nothing.
|
||||
wavs/115.wav|you'd think that would outrage some of the senators, but instead, as Padme went from colleague to colleague, pleading her case.
|
||||
wavs/116.wav|She found that even the ones who were against the bill before suddenly thought the Republic needed nothing more than more clones.
|
||||
wavs/117.wav|Everyone cared about their own self preservation over the people of the Republic, and she could do nothing.
|
||||
wavs/118.wav|Some minds can't be altered no matter what they hear, Bail said, when they met in his office. From my experience, Padme said.
|
||||
wavs/119.wav|It depends a great deal on who's sending the message. No, they would not listen to her. That was clear. But they might listen to bail.
|
||||
wavs/12.wav|The Separatists ordered more droids, and the war grew bigger. That was how it would go, on and on, until everything was destroyed.
|
||||
wavs/120.wav|Bail was the best Speaker in the Senate. Everyone respected him. He had, dignity. Bail needed to give a speech before the whole Senate.
|
||||
wavs/121.wav|He gazed at her, and then nodded his assent. He would do it. For the first time since Mina's death, Padme felt a spark of hope.
|
||||
wavs/122.wav|Perhaps one great speech could change the course of the war. Perhaps one great speech could save the Republic. Maybe that hope.
|
||||
wavs/123.wav|was what had made her so careless. Maybe it simply had never occurred to her that she might be in danger.
|
||||
wavs/124.wav|After going to plea with Senator Christo at his house the evening before the vote, she decided to walk alone back to her speeder, but when she got to where her speeder was parked,
|
||||
wavs/125.wav|The driver was gone, and the speeder along with it. She looked around. It was so dark. Were those foot steps?
|
||||
wavs/126.wav|She slipped around a corner and ducked into an alleyway, blaster poised. Then someone grabbed her, a burly bounty hunter.
|
||||
wavs/127.wav|who looked like a giant armored bug jumped in front of her and roared. Another one had taken hold of her from behind. Others had tried to kill Padme enough times by then.
|
||||
wavs/128.wav|that she knew how to channel all her panic into fighting back. She was not going to let Banking Clan goons silence her.
|
||||
wavs/129.wav|Find a way out. Get away! She thrashed. And struggled. Being small could be an advantage. People underestimated you.
|
||||
wavs/13.wav|But this time, there was a new wrinkle. The Senate's war funds were nearly extinguished. They simply could not afford more clones.
|
||||
wavs/130.wav|Armored Bug came at her with a knife, and she thrashed more, giving him no clear target. She slapped her blaster away, and she struggled against the one who held her.
|
||||
wavs/131.wav|He smelled like the Leonorm's swamp, and burst free. She ducked ahead, but armored bug tripped her, and next thing she knew his knife was at her throat.
|
||||
wavs/132.wav|And then two Coruscant police droids shone their lights in the alleyway. Padme pushed armored bug away and stood with the droids with one glance back.
|
||||
wavs/133.wav|The swamp smelling one who had hold of her was a petroleum with an eyepatch. She sprinted away, and then the bounty hunters attacked the droids.
|
||||
wavs/134.wav|Padme was not going to hang around and see who won that fight. She ran out of the alley and darted toward an empty speeder bike.
|
||||
wavs/135.wav|Senators were not generally supposed to hijack speeders, but these were extenuating circumstances. Get away. Get away!
|
||||
wavs/136.wav|The words repeated in her head as she charged forward, the bounty hunters close behind her. Then armored bug hit a button on his wrist and a cable shot out.
|
||||
wavs/137.wav|Attaching itself to her speeder. He was hanging off her speeder, with swamp stink, following on another speeder. One problem at a time Padme.
|
||||
wavs/138.wav|armored bug first. He wanted to go for a ride? Fine. Padme slammed her foot on the gas and sped forward.
|
||||
wavs/139.wav|Bug pressed a button on his armor and, suddenly, the cable was retracting. He was getting closer. He wanted more, then? Hadn't I dared write?
|
||||
wavs/14.wav|Padme had entertained a small hope that this, finally, might lead the Senate to discuss peace. But she should have known better. War is good business.
|
||||
wavs/140.wav|then left, darting in and out of traffic while the bounty hunter banged and bounced against oncoming speeders stink was getting close enough to be a problem.
|
||||
wavs/141.wav|She dragged Bug over a series of posts, then through a stack of crates. Did he like that? BAM!
|
||||
wavs/142.wav|Swap sink slammed into her from the side. She slammed him back. Suddenly the cable tugged again. And Bug was on her bike.
|
||||
wavs/143.wav|He grabbed for her, Hadme pulled at the fuel line, and fuel shot up into his face. They sped forward, fuel spraying into Bugs face.
|
||||
wavs/144.wav|Stinks like ramming into her and then police sirens a police speeder chase them.
|
||||
wavs/145.wav|while a giant metal bug person writhes on the back of one, out of the ordinary. But Padme did not have time for the police. She flammed stink hard.
|
||||
wavs/146.wav|And he veered away. Bug was on her again. So she ducked under a bridge and then, BANG! Slammed him into a lamp. He was off.
|
||||
wavs/147.wav|She sped forward, but somehow Stink was behind her again, with Bug now on his bike. She turned a corner, into a police blockade.
|
||||
wavs/148.wav|She stopped the bike as police cruisers surrounded her. She never thought she'd be so happy to be arrested.
|
||||
wavs/149.wav|Back in her apartment, Tecla fretted over Padme. Hello there, I'm Padme, from Naboo.
|
||||
wavs/15.wav|The Senate should deregulate the bank so the Republic could borrow more money, whose techno union would profit from that same deregulation. Yes.
|
||||
wavs/150.wav|The hand maiden asked, there's nothing they can do. I know who did it. You show it love, you show it light, and you hope it chooses the light.
|
||||
wavs/151.wav|They were bounty hunters, paid to stop me from voting against the troop increase. What has happened to democracy? And why doesn't anyone seem to care?
|
||||
wavs/152.wav|You do, Tecla said. You're not like most politicians. Padme nearly scoffed. If only that were enough.
|
||||
wavs/153.wav|Padme turned to look at her hand maiden, her friend. It wasn't true. Maybe it had been true once, but in the chaos of war, she'd lost sight of everything.
|
||||
wavs/154.wav|She'd been running all over Coruscant, trying to get the Senators to care about the suffering of their people, and she'd never asked her loyal friend.
|
||||
wavs/155.wav|If her family was suffering, she was exactly like most politicians, but she wouldn't be anymore. She could have been killed that night, if they killed her.
|
||||
wavs/156.wav|Let it be for being the person she wanted to be. Tecla, tell me, how is your family? Tecla tilted her head.
|
||||
wavs/157.wav|Padme's heart nearly broke. Of course they weren't fine. How is the war affecting them? Tecla eyed her uncertainly.
|
||||
wavs/158.wav|Patmay did not break her gaze. How? Please tell me. Tell me how it's been getting worse. She patted the couch next to her.
|
||||
wavs/159.wav|She should have been asking these questions all along. But she would ask now. Maybe it was the end of the Republic. Maybe she would lose everything else.
|
||||
wavs/16.wav|That would mean the Banking Clan could do whatever they wanted. But wasn't that a small price to pay for safety and freedom? Exhorted Holly Bertone.
|
||||
wavs/160.wav|but she would not lose her soul. It was the morning of the vote. Her conversation with Tekla replaced the despair she'd been feeling with resolve.
|
||||
wavs/161.wav|She would fight for her people, and she would not stop. They could send all the bounty hunters they wanted after her.
|
||||
wavs/162.wav|She would not stop fighting. If she could find a way to survive with Armored Bug and Swamp Stink after her, she could survive the corruption of the Galactic Senate.
|
||||
wavs/163.wav|She was ready, ready to stride into the Senate chamber and support Bail, and then the message came in. Bail had been attacked on his way to the Senate chamber.
|
||||
wavs/164.wav|He sent a message to Padme on his way to the hospital. You must address the Senate. Padme shook her head. If they didn't listen to me before,
|
||||
wavs/165.wav|Why would they listen to me now? Tekla gave her a small smile. Because you do listen. You understand.
|
||||
wavs/166.wav|what the people are going through. Please, your people are waiting for you. It is not supposed to be me, but it is her.
|
||||
wavs/167.wav|and she will fight. So Padme takes a deep breath and strides in. She hears me deechy proclaiming. Padme announces.
|
||||
wavs/168.wav|The whole chamber goes quiet, all eyes are on her, and suddenly she is not afraid. She will speak for the people.
|
||||
wavs/169.wav|She draws herself up and she begins. She has no mask. She has no strategy. All she can do is speak from the heart.
|
||||
wavs/17.wav|the senator whose planet produced and sold the clones. It was astonishing to Padme that anyone took them seriously when their motives were so clear.
|
||||
wavs/170.wav|So she tells them about Tecla, how Tecla's district rarely has electricity and running water as a result of the war.
|
||||
wavs/171.wav|how children there can only bathe every two weeks, how they have no light by which to read or study at night. She feels her words reverberate through the chamber.
|
||||
wavs/172.wav|The air crackles. No one is calling her traitor. When she finishes, there is a moment of silence. And then, cheers.
|
||||
wavs/173.wav|She feels the change in the room. She feels every one of them thinking of the people back home. She feels the Republic and its strength.
|
||||
wavs/174.wav|she feels it take one step back from the brink. The bill is defeated. She knows even before the vote is counted. Who knows what tomorrow will bring?
|
||||
wavs/175.wav|But today, the Senate showed itself to be more concerned about the people of the Republic than its own coffers. This is why she is here.
|
||||
wavs/176.wav|This is how things are supposed to be. And this is why she believes in the Republic. It is not without corruption.
|
||||
wavs/177.wav|It is not without darkness, but there is good at its core, and just because something good has darkness in it.
|
||||
wavs/178.wav|doesn't mean you abandon it. Just because there is darkness in something does not mean you do not love it.
|
||||
wavs/18.wav|But it was wartime, and profiteers masqueraded as patriots. Padme knew all about masks. When you were queen.
|
||||
wavs/180.wav|Ha ha ha ha. has fairly Dogsai.
|
||||
wavs/181.wav|The five besteston.
|
||||
wavs/182.wav|Ha ha ha ha ha ha ha ha ha ha!
|
||||
wavs/183.wav|The Republic needs your help. Could you please help me? I could use your assistance, please. Hello, I am Padme Amidala of the Republic Senate.
|
||||
wavs/184.wav|It is nice to see you. I'm pleased to meet you. Hello there. How are you? It's nice to meet you. I'm Senator Padme Amidala.
|
||||
wavs/186.wav|Where are you from? Greetings from the Republic Senate. It's nice to see a friendly face.
|
||||
wavs/187.wav|Hello! From which star system are you? I am here representing the Republic Senate. Hi! Nice to see you!
|
||||
wavs/188.wav|I am honored. It's a pleasure to get to know you. We'd better get going. The Republic's diplomatic issues aren't going to resolve by themselves.
|
||||
wavs/189.wav|This place would make a lovely retreat. I sure miss Annie. I'm sure I could use this time to compose a speech for the Galactic Senate.
|
||||
wavs/19.wav|You must keep your face blank, as if you had never felt an emotion in your life. In the Senate, you wore a different kind of mask.
|
||||
wavs/190.wav|I really ought to use this time to practice my blaster skills. I, mean my, diplomatic negotiations.
|
||||
wavs/191.wav|Ah, it's nice to have a much needed rest. I believe negotiations are in order? Now seems as good a time as any to relax.
|
||||
wavs/192.wav|It's hard for me to just wait for something to happen. I have things to do, really. I have better use for my time than this. I'll just wait here.
|
||||
wavs/193.wav|Huh. It might be time for me to stir up a little, diplomatic unrest. Oh! Excuse me! Why would you do that?
|
||||
wavs/194.wav|I beg your pardon? The nerve! That was uncalled for! Violence is rarely the answer. Oh, my. I didn't see you there.
|
||||
wavs/195.wav|I'm sure we can resolve this peacefully. The Senate won't stand for this. This isn't very diplomatic. You would strike a senator?
|
||||
wavs/196.wav|I'm going to write a very strongly worded letter about this. I'm sure you didn't mean it. Let's not do anything we'd regret.
|
||||
wavs/197.wav|But I have diplomatic immunity! Is that what you call negotiating? Look out! We're surrounded! And I don't think they want to negotiate!
|
||||
wavs/198.wav|Get your blaster ready. Here they come. Careful! Ah! What? Oh, my. Anakin, it is so good to see you.
|
||||
wavs/199.wav|I've missed you, Anakin. Please tell me you're well. How goes the battle, Anakin? I have missed you, my love. Tell me you will return to my side soon, Annie.
|
||||
wavs/2.wav|and try to convince her fellow senators to vote against a bill to commission more troops for the war against the separatists. And all she can think.
|
||||
wavs/20.wav|If you were on the side of continual war, you could contort your face in all kinds of ways. Sorrow. Horror. Out rage.
|
||||
wavs/200.wav|Anakin it pleases me to see you are doing well. Oh, Annie. I fear for you out in battle. Hello general Skywalker.
|
||||
wavs/201.wav|Master Obi Wan, I'm so glad to see you. Hello, Master Kenobi. How are you, Master Kenobi? How are your dealings with the Separatists?
|
||||
wavs/202.wav|It is good to see you Obi Wan. I'm so glad to see you master Kenobi. I always feel safe when the Jedi are near. Master Kenobi.
|
||||
wavs/203.wav|Hello, Master Kenobi. Jedi Master Kenobi, greetings. Hello, Ahsoka. It is so good to see you. Hello, Padawan Tano.
|
||||
wavs/204.wav|Ahsoka, Anakin tells me you will be a great Jedi someday. Hello Ahsoka my friend. it is so good to see you Ahsoka so I hope.
|
||||
wavs/205.wav|Padawan Tano. Hello. Padawan Tano. Ahsoka! I'm always so glad to see you. Jedi Master Yoda, it is a pleasure to see you.
|
||||
wavs/206.wav|Hello, Master Yoda. Master Yoda, how are you? I hear the Jedi are doing great things to help the Republic, Master Yoda. The Senate thanks you.
|
||||
wavs/207.wav|Greetings, Jedi Master Yoda. Hello, Master Yoda. Master Yoda, Master Yoda, you're looking well. You! Get away from me!
|
||||
wavs/208.wav|I thought you died on Naboo. What are you doing here, Sith? Maul! What do you want? You will pay for all the wrong you have done, Maul.
|
||||
wavs/209.wav|What do you want, Sith? You will show respect to a Senator, Maul. State your reason for being here, Sith. I'm on my way to the starport now.
|
||||
wavs/21.wav|And no one cared what was underneath the mask, if you were against the war, if you were a partisan, if you were young, if you were every thing Padme was.
|
||||
wavs/210.wav|If you will excuse me, I'll be sure to call. You can't do this! We are here on a mission of hope! To end this destructive conflict before it!
|
||||
wavs/211.wav|The Jedi are here. Please, you must help us. We're trapped. I knew the Jedi would come to aid us. Darth Maul is holding us hostage.
|
||||
wavs/212.wav|Be careful. I fear we are the bait in Darth Maul's trap. Maul is here. He wants to destroy every one of us. Thank you, Master Jedi.
|
||||
wavs/213.wav|Delegates from both the Republic and the Confederacy will be attending. Padawan Tano, without your help.
|
||||
wavs/214.wav|Darth Maul would have ruined any chance for a peaceful end to the Clone Wars, but now we can try to work toward a ceasefire.
|
||||
wavs/215.wav|Yes, the Supreme Chancellor has given me his blessing to host a peace conference in Theed. I thought my orders were clear, Master Jedi.
|
||||
wavs/216.wav|Anakin I know me what about you, but he said there was no way we could stop it, but Anakin don't be late So were you.
|
||||
wavs/217.wav|Sorry, Master Kenobi. That was me. Anakin directed me to a power regulator and I just pressed every button I could find.
|
||||
wavs/218.wav|This is Senator Amidala. I've discovered a secret Separatist base on Before, near the Naboo Sun. There's a lot of activity. It looks like they're,
|
||||
wavs/219.wav|Uh oh, I think I've been spotted. This is Senator Amidala. You must destroy this base at all costs. Do not,
|
||||
wavs/22.wav|You had to keep your face calm, reserved. You could show a bit of passion, but just a bit. You were too much and you were too emotional.
|
||||
wavs/220.wav|Yes, it was secretly given to him by the Supreme Executive of the Banking Clan himself. If they leave the Separatist Alliance, it will go a long way to shortening this war.
|
||||
wavs/221.wav|This is Senator Amidala. I'm afraid it's much worse than that. I see now this whole thing was a trap, and I'm afraid I walked right into it.
|
||||
wavs/222.wav|I've overloaded the power system. On the lower levels, I'm fine, but I don't know for how long. Droids are everywhere. I'll be there.
|
||||
wavs/223.wav|This is where we're supposed to meet them. He's probably late again. Anakin! The bridge is out! Threepio! No! We can't leave yet!
|
||||
wavs/224.wav|I overheard Grievous. Their hyperdrive is almost repaired. I suppose you have a plan. Ever since I've known you, you've been playing with droids.
|
||||
wavs/225.wav|We came as soon as we could, my lady. Have you found any more droids? Finding a couple of battle droids will not be enough. Where'd they pick up all this mud?
|
||||
wavs/226.wav|The Eastern Swamps. I think Jar Jar just found out the location of that lab. May I recommend General Kenobi and General Skywalker?
|
||||
wavs/227.wav|Relations with the Gungans are a little tense right now, but they trust General Kenobi like one of their own. I want as much information as possible before the Jedi arrive.
|
||||
wavs/228.wav|See if you and Three pee o can download any of the other battle droids memory. I'm going to find that lab. Come on Jar Jar, who are you?
|
||||
wavs/229.wav|We think the virus that made your animals sick came from the trees. You stay here. You'll be going home soon, I promise. I'll send some soldiers to pick you up and take you back to your home.
|
||||
wavs/23.wav|Too little, and you were a protocol droid. So Padme put on her senator mask and stood up. And there was some right on schedule.
|
||||
wavs/230.wav|Keep your eyes open. Look for anything out of the ordinary. No way we're going to open this. Why are you holding us? I was about to ask you the same thing.
|
||||
wavs/231.wav|The blue shadow virus? I thought that deadly disease was extinct. Are you insane? It's a deadly disease!
|
||||
wavs/232.wav|No life forms are immune to it. That's why it was eradicated. Annie, how about the next time you rescue me?
|
||||
wavs/233.wav|Before you kill all the battle droids. Missing bomb? I saw Dr. Vindy give a little droid a bomb. Hey there, little guy.
|
||||
wavs/234.wav|How about you hand that over to me? Ahsoka, I found the last bomb. It looks like the chamber that holds the virus is missing.
|
||||
wavs/235.wav|Sound the alarm! Don't blame yourself. These things tend to happen in a war zone. I hope that their sacrifice brings us closer to peace.
|
||||
wavs/236.wav|I can't, Annie. I have to bring this bill before the Senate. It's important. Not more important, but important.
|
||||
wavs/237.wav|The work we both do is in service to the Republic, to protect those who would otherwise be powerless to protect themselves. No, Anakin, I can't.
|
||||
wavs/238.wav|A Jedi lightsaber is, wow, it's heavier than I thought. If all you want to do is make fun of me, Senator Organa, how good to see you. What is it?
|
||||
wavs/239.wav|Privacy invasion, Bill. Of course. I can't let them search me. I have something they must not find. I am Padme.
|
||||
wavs/24.wav|He intoned. She had to pretend it was a serious question, because somehow saying that he only cared about his own profit was against the rules.
|
||||
wavs/240.wav|The Galactic Senate will not treat with terrorists. Another daring rescue, Master Jedi. Yes, of course, Senator. Worried about public opinion.
|
||||
wavs/241.wav|But he wants us to know how very sorry he is. I hope you're right, Uncle. You've been doing an amazing job rallying votes to our side.
|
||||
wavs/242.wav|Exciting isn't exactly the word I would use. I think terrifying is more appropriate. I learned it from you. See you inside, Senators.
|
||||
wavs/243.wav|The creation of more warriors will not end this war. The financial costs alone will bankrupt and cripple the republic.
|
||||
wavs/244.wav|By adding more clones to the conflict, we are only escalating the destruction. I understand. I'll do whatever is necessary to succeed in my mission.
|
||||
wavs/245.wav|not winning the war, which is why we must vote for this resolution to promote more diplomacy.
|
||||
wavs/246.wav|and to bring an end to this killing and hatred. Thank you. The only thing I find unpatriotic is your warmongering.
|
||||
wavs/247.wav|Thank you. But perhaps we should wait till we actually win the vote before we make a victory speech. This is a private conversation.
|
||||
wavs/248.wav|Committing more troops to the front lines will not allow diplomacy to resume. What we need is to get his resolution passed.
|
||||
wavs/249.wav|I know. No one could ever take his place. What's happened? What makes you think it was murder? That's not it. Perhaps,
|
||||
wavs/25.wav|And that set off more outrage. A building wave that threatened to crash through the chamber and drown them all. But then bail spoke.
|
||||
wavs/250.wav|Someone was upset about the clone troop bill currently on the floor. It's very controversial. No one will give the vote their full attention until they know what's happened to them.
|
||||
wavs/251.wav|Then we'll have time to conduct our own investigation. Well, he didn't exactly inspire confidence, did he?
|
||||
wavs/252.wav|We did. We'll have a far easier time looking into this than, indeed, I am. I'd rather do this quietly. I don't need a Guardian.
|
||||
wavs/253.wav|Very well. I have no objections. And I know exactly where to start. You both opposed Anno's ideas in the Senate. With enough at stake.
|
||||
wavs/254.wav|Maybe you decided to silence his voice, for good. Fine, I will go look. But whatever we find, I'll have more questions for both of you.
|
||||
wavs/255.wav|I had some information about a lead here at the docks. My friend was murdered. I don't care about rules. We alerted the killer.
|
||||
wavs/256.wav|What if we were sent here on purpose? Yes! What if this was all a setup? Sent us here, just so he could kill us.
|
||||
wavs/257.wav|Agreed. I think, in this instance, the Inspector is right. She was the only other one in the room with us. I had to try.
|
||||
wavs/258.wav|If you see injustice, you can't wait for someone else to fix it. You must stand up and get involved. If the poison wasn't all our drinks,
|
||||
wavs/259.wav|Lolo would have died too. She'd have been poisoned too. Unless she didn't drink. But you drank. You didn't drink.
|
||||
wavs/26.wav|urging them to slow down, to research the bill and its consequences, and his steady voice worked its magic over the room.
|
||||
wavs/260.wav|No! He made a mistake, Lolo! He was sorry! After all that, we lost. Of course, you were right, Chancellor.
|
||||
wavs/261.wav|Master Kenobi explained the problem. I'm here to help. It has no voice to defend itself. Anakin, we have to be that voice.
|
||||
wavs/262.wav|It's what we're capable of that frightens me. A creature's life, maybe even an entire species, is at stake. Doesn't that at least warrant a discussion?
|
||||
wavs/263.wav|Isn't that precisely the point of a democracy? How is killing the last of a species, in secret and without debate, good for anyone?
|
||||
wavs/264.wav|No, Mr. Speaker. I do not. Evacuate the staff to the underground shelters. Does it have to be destroyed? I wish we had never brought the beast here.
|
||||
wavs/265.wav|Considering the circumstances, I'll take the risk. Duchess, it's good to see you. If your government has trade concerns, we can talk.
|
||||
wavs/266.wav|Many systems have been affected. Everyone in the Republic has neglected Mandalore, and there are those of us who would still vote to give you any help you require.
|
||||
wavs/267.wav|We are making progress in the Senate. Overwhelmed. Perhaps they will listen to a new voice. Ruling Council, may I speak?
|
||||
wavs/268.wav|I hear your worries, your frustration, but the longer you argue the more your people suffer. You are right. New trade routes are essential to survival.
|
||||
wavs/269.wav|But the black market is no substitute for legitimate and legal trade. The Republic can provide security.
|
||||
wavs/27.wav|The air settled. The gathering calmed. The Senate was adjourned. Padme stalked into the hallway with Anakin and Ahsoka. Something had to be done.
|
||||
wavs/270.wav|As you know, in the Senate, the Chancellor says it's going very well, but my sources say otherwise. There are times I wish I could follow Mandalore's lead.
|
||||
wavs/271.wav|Neutrality, and not just in the war. There are still those of us who work to overcome the corruption and believe it to be possible.
|
||||
wavs/272.wav|means of direct communication, and locations you should investigate. So, where do we start? It's not your fault. The school must have an import log, correct?
|
||||
wavs/273.wav|So we should be able to find out where the tea came from. It looks like the school's import log has been erased. All this because you were greedy?
|
||||
wavs/274.wav|and a customs official reports these to the government. I must say, when I came to visit, I hadn't pictured us in such an informal setting.
|
||||
wavs/275.wav|But one can only survive the rigors of courtly formalities for so long. Impossible! We witnessed it with our own eyes! And what about when you're not watching?
|
||||
wavs/276.wav|It wasn't Death Watch, Prime Minister. It was a group of black market smugglers. What they didn't count on was the process would make the drinks poisonous. You must have hope, Satine.
|
||||
wavs/277.wav|I will speak with Master Yoda. Don't lose hope, my friend. Ahsoka! It's so good to see you. How have you been? What makes you believe that?
|
||||
wavs/278.wav|This is troubling. Captain, please take all necessary precautions. Yes, Bail Organa and I are leading a conference concerning the refugees from the war.
|
||||
wavs/279.wav|I leave for Alderaan in the morning. Ahsoka, the refugee situation is much too crucial to ignore. I called this conference.
|
||||
wavs/28.wav|They needed another way, she turned to Anakin. You must ask the Jedi Council to speak with Chancellor Palpatine. Anakin threw up his hands.
|
||||
wavs/280.wav|It could make an enormous difference in policy. It's vital that I go. Well, I suppose it couldn't hurt. Besides, I enjoy your company.
|
||||
wavs/281.wav|Of course you can join me as extra security. You'll learn to play in time, Ahsoka. Someday, you'll even beat me. What's on your mind?
|
||||
wavs/282.wav|When I was queen, I felt the same insecurities as you do now. It was ultimately up to me to run the entire Naboo system.
|
||||
wavs/283.wav|Oh yes. But I have learned to trust in myself, and you will too. Absolutely. Yes, Captain.
|
||||
wavs/284.wav|I'm fine. Bail, it's so good to see you. Thank you so much for hosting this conference. Of course, Pato Antano. If you'll excuse me.
|
||||
wavs/285.wav|I haven't lost faith in you, Ahsoka. We are taking all the necessary precautions, correct, Captain? Ahsoka, in your vision, does Ora succeed?
|
||||
wavs/286.wav|Isn't it just beautiful? Ahsoka, I can't stop living my life. You forget, I'm a friend of the Jedi. I'm no stranger to taking risks.
|
||||
wavs/287.wav|What is it? I wanted to first thank you all for coming. This is a cause that is very important to me. You did all you could.
|
||||
wavs/288.wav|They will follow me wherever I go. It is the greatest weapon wielded against those who would stand up for truth and justice. And together we shall represent them.
|
||||
wavs/289.wav|And I know there are those individuals in the galaxy who would seek to promote fear and spread chaos. Know that a chorus of thousands shall rise up in its place.
|
||||
wavs/29.wav|Before Padme could respond, Ahsoka said, why not? Aren't we Jedi Knights? Isn't it our duty to advise the Chancellor?
|
||||
wavs/290.wav|For you have no dominion over the righteous. We are the defenders of truth. Ahsoka, I told you.
|
||||
wavs/291.wav|I'm no stranger to taking risks. Captain, she's stunned. His planet is in crisis. His people are starving. He's a very old family friend.
|
||||
wavs/292.wav|I could not refuse his plea for help. This is a mission of peace. I put my faith in diplomacy.
|
||||
wavs/293.wav|We can't solve all of our problems by throwing troops at them! Without Ahsoka's foresight, I fear things would have gone quite differently.
|
||||
wavs/294.wav|I will follow your advice, Chancellor. Thank you. I've been thinking. Ara Singh said the person who hired her simply wanted revenge for something I did to them.
|
||||
wavs/295.wav|Yes, but with Ahsoka's added details, I know someone who fits the description. Wait, no.
|
||||
wavs/296.wav|The tendrils belong on the main table between Anakin and Senator Aang. Three pee o. It's so good to see you, Senator Aang. Three pee o, you've done a magnificent job.
|
||||
wavs/297.wav|Members of the Senate, do you hear yourselves? More money. More clones. More war. Say nothing of fiscal responsibility.
|
||||
wavs/298.wav|What about moral responsibility? Hasn't this war gone on long enough? Of course not! But negotiation might be a better course of action.
|
||||
wavs/299.wav|You must ask the Jedi Council to speak with Chancellor Palpatine. A peaceful solution is the only way out of this morass of war.
|
||||
wavs/3.wav|is that it's not supposed to be her. She's even convinced Bail Organa that she is the wrong person. She's still too new, too young.
|
||||
wavs/30.wav|Anakin sniffed. After today's debate, Padme muttered darkly, I was hoping she learned a great deal. Truthfully, Ahsoka said.
|
||||
wavs/300.wav|After today's debate I was hoping she learned a great deal. Maybe talking to the Jedi Council isn't the role for you after all. Thanks for your help. Come on Ahsoka.
|
||||
wavs/301.wav|You told me to teach her about politics. So I'm going to. He is a she, a senator in the confederacy of independent systems.
|
||||
wavs/302.wav|The Separatists used to be a part of the Republic. I was close with many of the Senators who left. I may not agree with them, but they're more than pawns.
|
||||
wavs/303.wav|They say official meetings would only legitimize the Separatists. You just gave me an idea. You're a Jedi, and Jedi are allowed to travel to neutral worlds like Mandalore.
|
||||
wavs/304.wav|Where we could then board a cargo ship to a Separatist system. It's just that you could get us through to meet with her and, I haven't seen her or her family in so long.
|
||||
wavs/306.wav|She was my mentor when I was growing up on Naboo. Yes, how things have changed since the last time we met. I sense Dooku's dirty hand in all of this.
|
||||
wavs/307.wav|I forgot. You actually admire the man. The Republic Senate is holding a critical vote on whether or not to escalate the war effort.
|
||||
wavs/308.wav|However, many of the delegates are undecided as to what to do. I am certain if you could convince your representatives to extend an olive branch of peace towards the Republic,
|
||||
wavs/309.wav|There might be enough sympathy in the Senate to finally open negotiations. That's all I ask. To hope. This is goodbye.
|
||||
wavs/31.wav|I didn't understand any of it. I know the separatists are evil, but all anyone argued about was banking deregulation.
|
||||
wavs/310.wav|Jar Jar, you would be doing me a great favor by staying with the ship. I need you to watch over Three pee o. You know how he always gets himself into trouble.
|
||||
wavs/311.wav|I won't be long. We've been friends since I was a little girl, when you were my father's strongest ally in the Senate. And of course I'd come to help you.
|
||||
wavs/312.wav|I'm sure the Republic Senate will approve a relief effort. The vote was postponed, but you will get your food, Your Excellency.
|
||||
wavs/313.wav|We would be remiss, if not irresponsible, to reject the Separatist proposal. Cannot be trusted. He will bring war to your system just as he did to mine many years ago.
|
||||
wavs/314.wav|I don't understand. If I might speak with you confidentially, I know that this is sincere. Does it matter, Chancellor, if the result is an end to the war?
|
||||
wavs/315.wav|There's always a choice. To live in fear is no life at all, given that the separatists have put a call for negotiations on the table.
|
||||
wavs/316.wav|The need for additional troops seems ill timed. But it was the Separatist Congress that issued the Bill of Peace! That's not true! It's not too late!
|
||||
wavs/317.wav|You can stop this madness! I'm returning your Padawan. Chancellor Palpatine! One alternative might be to stop the war, not escalate it!
|
||||
wavs/318.wav|May I remind the Senators that the peace proposal was made prior to their assault. Wants us to continue the fight.
|
||||
wavs/319.wav|It's a calculated attempt to destroy the peace process. Not everyone in the Confederacy wants this. I know this for a fact. I can't believe it.
|
||||
wavs/32.wav|interest rates and, well, almost nothing about what we're fighting in the first place. Padme smiled sadly.
|
||||
wavs/320.wav|I just can't believe the Republic would target, Senator. What can we do? Right. Let's go, Uncle. You know these Banking Clan people.
|
||||
wavs/321.wav|Plus, you owe me for telling such a bad joke. I'll see, this bill is shortsighted. Millions of clones won't win this war.
|
||||
wavs/322.wav|The only winner will be the banking clan. They wanna pass this bill so badly, they're using scare tactics to sway votes.
|
||||
wavs/323.wav|Then why are you voting for additional troops? As long as Senators are being threatened and attacked, I'm afraid we don't stand a chance.
|
||||
wavs/324.wav|Even so, we're still at least six votes short of a majority. And you saw how effective my plea was today. You're the finest public speaker I know.
|
||||
wavs/325.wav|If anyone can convince the Senate that voting for this bill will bankrupt the Republic, both financially and spiritually, I urge you to speak before the full Senate.
|
||||
wavs/326.wav|Good. In the meantime, I'll pay another visit to those still undecided. Thank you. This way, uncle. They are people! Is there anything we can do to get you to change your mind?
|
||||
wavs/327.wav|Senator Organa is preparing to speak before the full Senate, so you are open to voting with us. It's better than a no.
|
||||
wavs/328.wav|I'm sure when Christo and the others hear what Bail has to say, they will vote our way. My driver's only a block away. I think I'd like to walk. I can take care of myself.
|
||||
wavs/329.wav|Plus, I can use the fresh air. There's nothing they can do. I know who did it. They were bounty hunters.
|
||||
wavs/33.wav|While Ahsoka's viewpoint on the Separatists had all the nuance of a Senate debate, she was exactly right on what had happened in that room.
|
||||
wavs/330.wav|Paid to stop me from voting against the troop increase. He carries a certain weight. He's seen as a voice of reason. I've been against this bill from day one.
|
||||
wavs/331.wav|If they didn't listen to me before, why would they listen now? Like so many of the people that we tell ourselves, we're here to serve.
|
||||
wavs/332.wav|Tekla lives in a district that rarely has electricity and running water as a result of the war.
|
||||
wavs/333.wav|Her children can now only bathe every two weeks, and they have no light in which to read or study at night.
|
||||
wavs/334.wav|with no thought for what the people need to survive. This war is meant to save them from suffering, not increase it.
|
||||
wavs/335.wav|It is not on the battlefield where Dooku will defeat us, but in our own homes. Therefore, it is our duty and our responsibility to defend our land.
|
||||
wavs/336.wav|to preserve the lives of those around us by defeating this bill. Is Boss Leoni calling for a march on feed? Of course it's not.
|
||||
wavs/337.wav|With all due respect, your course of action is based on lies. You must make your warriors stand down, or under someone's influence.
|
||||
wavs/338.wav|Who are we? Boss Leoni, don't you remember anything? I know, Jar Jar. The bandages have stopped the bleeding, but he's unconscious.
|
||||
wavs/339.wav|The resemblance is,remarkable. You! You look just like Boss Leone. I didn't realize it until you put the crown on.
|
||||
wavs/34.wav|That was the Galactic Senate for you. People were dying across the galaxy, and the Senate made it sound like a banking problem.
|
||||
wavs/340.wav|I'm not sure, Jar Jar. What do you want, Dooku? I can't do that. I can't, Jar Jar. With Grievous captured, we could win the war.
|
||||
wavs/341.wav|I know, Jar Jar. What is going on? What have you done here, Clovis? All of your idealism was just a front.
|
||||
wavs/342.wav|Why are you doing this? Listen to yourself. The Republic is sending its armada to take back the banks. You've brought war right where there cannot be war.
|
||||
wavs/343.wav|Your actions have destroyed the banks once and for all! Clovis, you have to turn yourself in. Let me go, Clovis!
|
||||
wavs/344.wav|No! Anakin, don't! I'm sorry, Anakin. I'm sorry. You know you will soon be destroyed.
|
||||
wavs/345.wav|I can't tell you how many times I've seen battle droids sliced in half by a lone Jedi. You made it! I'm rescued at last!
|
||||
wavs/346.wav|Hurry before the battle droids figure out what's happening. Thank you. Let's get out of here, Master Jedi. Three pee o, where's Jar Jar?
|
||||
wavs/347.wav|What about the Jedi that's not good, but I need you to stay calm go back to the ship and call for help what? battle droids.
|
||||
wavs/348.wav|Jar Jar, all right, then find a communications room and send out a distress signal. Hopefully there are some clone ships within range. I'll track down Jar Jar.
|
||||
wavs/349.wav|Jar Jar! Jar Jar, no. I think Jar Jar's dead, Three pee o. Hold it right there, Viceroy.
|
||||
wavs/35.wav|Anakin said, wars complicated Ahsoka, but let me simplify it. The Separatists believe the Republic is corrupt.
|
||||
wavs/350.wav|I think it's time to tell the Viceroy about our little secret, how you never meant to leave the Republic, and how you truly care what's best for your people.
|
||||
wavs/351.wav|It is the Republic that should be asking your forgiveness, my old friend. Far too often, we forget that our most important allies are our allies.
|
||||
wavs/352.wav|I wanted to compliment you on your speech. You were very brave in these difficult times. I know the Separatists have approached you to offer their help. Please do not take it.
|
||||
wavs/353.wav|The Senate will force the Trade Federation to resume trade. It reminds me far too much of Naboo's unscarred history. You certainly have a unique way of looking at things, Annie.
|
||||
wavs/354.wav|What is it, Ahsoka? I was afraid something like this would happen. I'm not so sure local authorities can handle it. Should you really proceed without the Council's approval?
|
||||
wavs/355.wav|Well, be careful, Ahsoka. I still can't believe they let you teach. I will do everything I can to prove your innocence, Ahsoka. Wait, where are you going?
|
||||
wavs/356.wav|You can't leave now. Until we hear from Anakin, let's work on your defense. The Republic recognizes the tragedy of war.
|
||||
wavs/357.wav|But there is nothing we can change that has already occurred. Anakin! That will be all, Threepio. Yes, Threepio. Now go!
|
||||
wavs/358.wav|How did you manage this? What happened to your military transport? You called this, home. The Naboo ambassador gave me something, I think,
|
||||
wavs/359.wav|I still have it here somewhere. It is. It'll be perfect. Five blossom bread. My specialty.
|
||||
wavs/36.wav|but they're wrong, and we have to restore order. And that was Anakin. He needed to believe in right and wrong, good and evil.
|
||||
wavs/360.wav|I know how to make lots of things. When I was little, I cooked every day. I've been saving it for a special occasion. I wish it could always be just like this.
|
||||
wavs/361.wav|Right now? I understand. Don't think you can read my mind. You finally found some time for me. I already told Master Yoda.
|
||||
wavs/362.wav|I don't want to spy on a colleague and an old friend. Why does that matter? That was before we were together. It's not your decision to make!
|
||||
wavs/363.wav|It's mine. Actually, I just changed my mind. You've convinced me that it's vital to learn what Clovis is doing. I accept the mission to spy on him.
|
||||
wavs/364.wav|Don't take it personally, Anakin. Duty comes first. Especially in wartime. At one point, Clovis and I were, close.
|
||||
wavs/365.wav|It was my choice to return things to a strictly professional level. Clovis didn't take it well. But I know I can regain Clovis's trust.
|
||||
wavs/367.wav|It's been good to see you again, Clovis. I didn't realize how lonely I was until tonight. Ah, you're taking a pleasure trip?
|
||||
wavs/368.wav|Maybe you can say a few words on my behalf. It's every day asking for trade concessions, but, I can't ever seem to make progress.
|
||||
wavs/369.wav|Are you inviting me for political reasons or because you want us to be friends again, I'll be happy to go with you.
|
||||
wavs/37.wav|And if something was not all good, all right, then to him it was evil. It made him a good Jedi, but a terrible politician.
|
||||
wavs/370.wav|It'll be like old times. Senator Clovis, please forgive me for arriving unannounced. I came here with the very same hope.
|
||||
wavs/371.wav|I believe in second chances. Three pee o, after that long trip, I think I need a walk.
|
||||
wavs/372.wav|Oh, I'm sorry to intrude. I was lonely, so I came looking for you, and I'm fine. I stood up too fast.
|
||||
wavs/373.wav|A tour sounds perfect. Yes, I'm sure. Padme? That tastes so good. I guess I was just thirsty.
|
||||
wavs/374.wav|You're so good to me, Clovis. I don't deserve your kindness. Because of you! I did it for the Republic!
|
||||
wavs/375.wav|I didn't want to believe that you were involved with the Separatists, but you are. You're a traitor! It's on its way to the Senate.
|
||||
wavs/376.wav|Your scheme is finished. We may never have a better chance to capture Count Dooku. We would like to send two Jedi to confirm you have Count Dooku.
|
||||
wavs/377.wav|Before delivering the ransom. Impossible. The Senate completed its vote. They've decided in favor of occupation. It was during your meeting with the Chancellor.
|
||||
wavs/378.wav|Your accident accelerated the Senate's decision. Republic forces are set to leave for Mandalore at sunrise tomorrow. Supreme Chancellor.
|
||||
wavs/379.wav|I think this should cast a new light on the so called evidence we saw earlier. The person to thank is Duchess Satine. She found the proof.
|
||||
wavs/38.wav|and no help to her at all. Padme headed to her office, motioning for Ahsoka to follow. There had to be a solution. There had to be another way.
|
||||
wavs/380.wav|The Senate held an emergency session, and the Republic forces have been ordered to stand down. We have some logistics to discuss in order to ratify the Senate's decision.
|
||||
wavs/381.wav|Welcome home, Chancellor. I'm thankful to the Jedi for bringing you here safely. Anakin, Ahsoka, welcome to the festival.
|
||||
wavs/382.wav|Are you that certain an attack is imminent? Once again you have all distinguished yourselves in the eyes of the Republic, and the people of Naboo are in your debt.
|
||||
wavs/39.wav|Surely the Separatists didn't want continual war, either. If only she could talk to Mina. Mina Bonteri was the enemy now.
|
||||
wavs/4.wav|Too partisan. Proving herself. Will she ever not be proving herself? It is supposed to be bail. Trusted. Respected.
|
||||
wavs/40.wav|A senator in the Confederacy, but once Mina was her friend, her mentor. Surely Mina wanted the war to end.
|
||||
wavs/41.wav|But it was illegal to talk to Separatists, because that would be legitimizing them. Which made it impossible to negotiate peace.
|
||||
wavs/42.wav|She spoke her thoughts out loud to Ahsoka, who couldn't believe it. Your friend is a Separatist? One of Dooku's pawns?
|
||||
wavs/43.wav|It's not that simple, she wanted to say. This was the problem. This was why the war would never stop, back in the Senate chamber.
|
||||
wavs/44.wav|Mott not Rab had called the Separatists, animals, Ahsoka, evil, and pawns. Anakin, wrong.
|
||||
wavs/45.wav|But what if things weren't so black and white? What if she could find another way? And that was when Padme got an idea.
|
||||
wavs/46.wav|Are you suggesting, Ahsoka asked after she explained her plan, that I use my status as a Jedi to smuggle you behind enemy lines?
|
||||
wavs/47.wav|Padme blinked. Time to try a different tack. It's just, she said carefully, that you could get us through to meet with her.
|
||||
wavs/48.wav|and I haven't seen her and her family for so long. But Ahsoka grinned. Relax, she said. I'll help you. Padme grinned back.
|
||||
wavs/49.wav|It was simple, in the end. As a Jedi, Ahsoka could get Padme to neutral systems, so they went to Mandalore, and then took a cargo ship to Raxus.
|
||||
wavs/5.wav|considered a voice of reason. Bail is the one they'll listen to, and the bill on the table is too important for them not to listen.
|
||||
wavs/50.wav|Mina Bonteri's current home, and the sight of the Separatist capital, they wrapped themselves in hooded cloaks and strode by battle droids as if they belonged there.
|
||||
wavs/51.wav|Padme had known that Raxxulan was a thriving city, but somehow she'd expected it to look different, shadowy and war torn.
|
||||
wavs/52.wav|Even though the war had no more come to Raxus than it had to Coruscant, Coruscant hadn't been attacked in a thousand years, and walking its streets,
|
||||
wavs/53.wav|You'd have no idea the galaxy around it was burning. Nonetheless, with a young Jedi at her side, if they were caught,
|
||||
wavs/54.wav|A republic senator was not supposed to be strolling on a Raxulan landing platform swarming with battle droids.
|
||||
wavs/55.wav|Well, it was better not to think about it, but they had a plan. The battle droids on Raxus were no less distractible than anywhere else in the galaxy.
|
||||
wavs/56.wav|and suddenly Padme was standing in front of Mina Bonteri. Mina said. Padme had forgotten how warm Mina's voice was.
|
||||
wavs/57.wav|How it could feel like an embrace, just when she needed one. In a moment, the rest of it all fell away. The Separatists. The war.
|
||||
wavs/58.wav|And they were simply two old friends, beholding each other after all those years. When they got to the Bonteri house, they were greeted by Mina's son, Lux.
|
||||
wavs/59.wav|who had been just a boy when Padme saw him last, Mina did not look that much older than she had. A little grayer, and something else too.
|
||||
wavs/6.wav|There is no end to the war in sight. Clones are being slaughtered, and the Separatists are gaining ground. The Republic keeps throwing money at it. Throwing clones at it.
|
||||
wavs/60.wav|Maybe a little sadder. But Lux was like an entirely different person. He's grown so much, Mina. Padme breathed when she and Ahsoka were inside the house.
|
||||
wavs/61.wav|It was a foolish thing to say, of course he had, but right now she felt foolish, Mina said gently. With all due respect, Ahsoka said.
|
||||
wavs/62.wav|As a Separatist, didn't you create this war? Padme turned to her. Ahsoka, Mina reassured. And then she turned her gaze to the young Jedi.
|
||||
wavs/63.wav|and the Jedi? Ahsoka straightened. Maybe I could speak with him, she said. Padme heard the unsaid words in her old friend's voice.
|
||||
wavs/64.wav|and looked at the rug, face burning. She hadn't known, Mina added. Ahsoka looked how Padme felt. She made an excuse and stepped outside.
|
||||
wavs/65.wav|leaving Padme alone with Mina. I'm so sorry, Padme said after a moment. Mina said. I didn't, Padme began.
|
||||
wavs/66.wav|Mina said. When Mina came back, carrying two glasses of wine, Padme was ready. They discussed the war in general terms, speaking like friendly politicians.
|
||||
wavs/67.wav|And then, slowly, speaking like any pair of friends might, so much so that when talk returned to the republic's crisis,
|
||||
wavs/68.wav|Padme said what she would to any other friend. I sensed Dooku's dirty hand in this. Mina's eyebrows quirked. She said dryly.
|
||||
wavs/69.wav|I forgot Padme said voice sharp you actually admire the man the words were out of her mouth before she could stop them.
|
||||
wavs/7.wav|Not realizing that the war is a fire that treats everything thrown at it as kindling. The bill on the table not only would expand the war,
|
||||
wavs/70.wav|Before she could remember, she was supposed to put all those feelings aside and try to talk peace. But talking like friends made her remember what it was like to be friends.
|
||||
wavs/71.wav|Before Mina had left the Republic, had sided with Dooku, had chosen betrayal, war takes everything from you.
|
||||
wavs/72.wav|Mina said after a moment. The question is how. Padme straightened, gathered herself, put on her diplomat mask.
|
||||
wavs/73.wav|That is why it was so urgent that I speak with you. The Republic Senate is holding a critical vote on whether or not to escalate the war effort.
|
||||
wavs/74.wav|However, many of the delegates are undecided as to what to do. Mina nodded slowly. That was what Padme wanted to hear.
|
||||
wavs/75.wav|I am certain if you could convince your representatives to extend an olive branch toward the Republic, there might be enough sympathy in the Senate to finally open negotiations.
|
||||
wavs/76.wav|Thank you, Mina. That's all I ask, Mina said, raising her glass to hope.
|
||||
wavs/77.wav|and hope was what she had when she and Ahsoka left Raxus. Thanks to Mina's efforts, the Confederate sent it with a hologram of Dooku presiding.
|
||||
wavs/78.wav|Had passed a resolution to initiate peace talks, Padme had said goodbye to Mina like a diplomat after a successful negotiation, but a little like an old friend too.
|
||||
wavs/79.wav|She would never understand why Mina Bonteri would side with Dooku, no matter what issues her friend had with the Republic. She would not try to understand.
|
||||
wavs/8.wav|It would bankrupt the whole Republic. It is supposed to be Bail. He has spent days on his speech. But here Padme is.
|
||||
wavs/80.wav|But right now, they were both on the side of peace. And maybe one day the war would end and they could really be on the same side again.
|
||||
wavs/81.wav|and try to repair what had been broken. She had hope. She carried it with her back to Mandalore, then back to Coruscant, to the Senate building.
|
||||
wavs/82.wav|and up to Chancellor Palpatine's office, where she told him about the Confederate proposal, omitting everything she had done to bring it about, he said.
|
||||
wavs/83.wav|Your Excellency, Padme said, every bit the proper Senator, we would be remiss if not irresponsible.
|
||||
wavs/84.wav|To reject the Separatist proposal, an end to the fighting would mean there's no need to borrow money for more clones. The Chancellor beckoned to her, then walked her away from the others.
|
||||
wavs/86.wav|he said. Padme bristled. He still talked to her like she was a child. I don't understand. Yes, yes, they could.
|
||||
wavs/87.wav|she weighed her options in a blink. If I might speak with you confidentially, she said. Chancellor Palpatine loved being in on secrets.
|
||||
wavs/88.wav|I know that this is sincere. I've been in contact with my old friend, Mina Bonteri, and the origin of the proposal is with her.
|
||||
wavs/89.wav|She smiled winningly. Does it matter, Chancellor, if the result is an end to the war? All the way up to her repulsor pod.
|
||||
wavs/9.wav|with mere minutes to decide what she is going to say, and all she can think is, it is not supposed to be me.
|
||||
wavs/90.wav|so she carried her hope with her to the Grand Convocation Chamber. Something was different. The other Senators felt it, too.
|
||||
wavs/91.wav|The air crackled, Padme drew all the excitement to her, and addressed the chamber. Bail added, it was time to vote.
|
||||
wavs/92.wav|Padme pressed her button. Nay, then there was a distant explosion. The whole building shook and the lights went out. Coruscant had been attacked.
|
||||
wavs/93.wav|A power generator bombed. The Separatists were blamed. It made no sense to Padme. They just opened peace talks.
|
||||
wavs/94.wav|But it was wartime, and no one cared about cents. Holly Bertone moved to immediately deregulate the banks, and the Senate approved in a flash.
|
||||
wavs/95.wav|More troops. More fighting. More death. More war. Always more war. But Bertone was not done.
|
||||
wavs/96.wav|Padme could not speak. Five million, Bail said. Of course, Bertone had an answer. Padme could not help herself.
|
||||
wavs/97.wav|That did it, someone shouted, and in the blink of an eye, wanting peace had come to mean being a traitor, but Padme would not give up.
|
||||
wavs/98.wav|hissed another senator. There was no point. She could say nothing. They were back to black and white, right and wrong, good and evil.
|
||||
wavs/99.wav|And if she was not pro war, she might as well be the enemy. A traitor. Then a murmur from Palpatine. A blip in the air.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
wavs/10.wav|You've been doing great! You do realize he's not a bear right?
|
||||
wavs/283.wav|We're supposed to be hunting down the missing relics and catching the bad guy. And we're your friends. That's your answer for everything.
|
||||
wavs/603.wav|Weather for the coronation is sunny skies! That tickles. Bring them up here would ya? Sky needs to build his strength. air drills, wing lifts, All that boring methodical stuff.
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user