ZeyuXie commited on
Commit
93c7dfc
1 Parent(s): 930de62

Upload 8 files

Browse files
app.py CHANGED
@@ -1,91 +1,135 @@
1
-
2
- import os
3
- import json
4
- import numpy as np
5
- import torch
6
- import soundfile as sf
7
- import gradio as gr
8
- from diffusers import DDPMScheduler
9
- from pico_model import PicoDiffusion
10
- from audioldm.variational_autoencoder.autoencoder import AutoencoderKL
11
-
12
- class dotdict(dict):
13
- """dot.notation access to dictionary attributes"""
14
- __getattr__ = dict.get
15
- __setattr__ = dict.__setitem__
16
- __delattr__ = dict.__delitem__
17
-
18
- class InferRunner:
19
- def __init__(self, device):
20
- vae_config = json.load(open("ckpts/ldm/vae_config.json"))
21
- self.vae = AutoencoderKL(**vae_config).to(device)
22
- vae_weights = torch.load("ckpts/ldm/pytorch_model_vae.bin", map_location=device)
23
- self.vae.load_state_dict(vae_weights)
24
-
25
- train_args = dotdict(json.loads(open("ckpts/pico_model/summary.jsonl").readlines()[0]))
26
- self.pico_model = PicoDiffusion(
27
- scheduler_name=train_args.scheduler_name,
28
- unet_model_config_path=train_args.unet_model_config,
29
- snr_gamma=train_args.snr_gamma,
30
- freeze_text_encoder_ckpt="ckpts/laion_clap/630k-audioset-best.pt",
31
- diffusion_pt="ckpts/pico_model/diffusion.pt",
32
- ).eval().to(device)
33
- self.scheduler = DDPMScheduler.from_pretrained(train_args.scheduler_name, subfolder="scheduler")
34
-
35
- device = "cuda" if torch.cuda.is_available() else "cpu"
36
- runner = InferRunner(device)
37
- event_list = [
38
- "burping_belching", # 0
39
- "car_horn_honking", #
40
- "cat_meowing", #
41
- "cow_mooing", #
42
- "dog_barking", #
43
- "door_knocking", #
44
- "door_slamming", #
45
- "explosion", #
46
- "gunshot", # 8
47
- "sheep_goat_bleating", #
48
- "sneeze", #
49
- "spraying", #
50
- "thump_thud", #
51
- "train_horn", #
52
- "tapping_clicking_clanking", #
53
- "woman_laughing", #
54
- "duck_quacking", # 16
55
- "whistling", #
56
- ]
57
- def infer(caption, num_steps=200, guidance_scale=3.0, audio_len=16000*10):
58
- with torch.no_grad():
59
- latents = runner.pico_model.demo_inference(caption, runner.scheduler, num_steps=num_steps, guidance_scale=guidance_scale, num_samples_per_prompt=1, disable_progress=True)
60
- mel = runner.vae.decode_first_stage(latents)
61
- wave = runner.vae.decode_to_waveform(mel)[0][:audio_len]
62
- outpath = f"output.wav"
63
- sf.write(outpath, wave, samplerate=16000, subtype='PCM_16')
64
- return outpath
65
-
66
-
67
- description_text = f"18 events: {', '.join(event_list)}"
68
- prompt = gr.Textbox(label="Prompt: Input your caption formatted as 'event1 at onset1-offset1_onset2-offset2 and event2 at onset1-offset1'.",
69
- value="spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031.",)
70
- outaudio = gr.Audio()
71
- num_steps = gr.Slider(label="num_steps", minimum=1, maximum=300, value=200, step=1)
72
- guidance_scale = gr.Slider(label="guidance_scale", minimum=0.1, maximum=8.0, value=3.0, step=0.1)
73
-
74
-
75
- gr_interface = gr.Interface(
76
- fn=infer,
77
- inputs=[prompt, num_steps, guidance_scale],
78
- outputs=[outaudio],
79
- title="PicoAudio",
80
- description=description_text,
81
- allow_flagging=False,
82
- examples=[
83
- ["spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031."],
84
- ["dog_barking at 0.562-2.562_4.25-6.25."],
85
- ["cow_mooing at 0.958-3.582_5.272-7.896."],
86
- ],
87
- cache_examples="lazy", # Turn on to cache.
88
- )
89
-
90
- gr_interface.queue(10).launch()
91
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import json
4
+ import numpy as np
5
+ import torch
6
+ import soundfile as sf
7
+ import gradio as gr
8
+ from diffusers import DDPMScheduler
9
+ from pico_model import PicoDiffusion
10
+ from audioldm.variational_autoencoder.autoencoder import AutoencoderKL
11
+ from llm_preprocess import get_event, preprocess_gemini, preprocess_gpt
12
+ class dotdict(dict):
13
+ """dot.notation access to dictionary attributes"""
14
+ __getattr__ = dict.get
15
+ __setattr__ = dict.__setitem__
16
+ __delattr__ = dict.__delitem__
17
+
18
+ class InferRunner:
19
+ def __init__(self, device):
20
+ vae_config = json.load(open("ckpts/ldm/vae_config.json"))
21
+ self.vae = AutoencoderKL(**vae_config).to(device)
22
+ vae_weights = torch.load("ckpts/ldm/pytorch_model_vae.bin", map_location=device)
23
+ self.vae.load_state_dict(vae_weights)
24
+
25
+ train_args = dotdict(json.loads(open("ckpts/pico_model/summary.jsonl").readlines()[0]))
26
+ self.pico_model = PicoDiffusion(
27
+ scheduler_name=train_args.scheduler_name,
28
+ unet_model_config_path=train_args.unet_model_config,
29
+ snr_gamma=train_args.snr_gamma,
30
+ freeze_text_encoder_ckpt="ckpts/laion_clap/630k-audioset-best.pt",
31
+ diffusion_pt="ckpts/pico_model/diffusion.pt",
32
+ ).eval().to(device)
33
+ self.scheduler = DDPMScheduler.from_pretrained(train_args.scheduler_name, subfolder="scheduler")
34
+
35
+ device = "cuda" if torch.cuda.is_available() else "cpu"
36
+ runner = InferRunner(device)
37
+ event_list = get_event()
38
+ def infer(caption, num_steps=200, guidance_scale=3.0, audio_len=16000*10):
39
+ with torch.no_grad():
40
+ latents = runner.pico_model.demo_inference(caption, runner.scheduler, num_steps=num_steps, guidance_scale=guidance_scale, num_samples_per_prompt=1, disable_progress=True)
41
+ mel = runner.vae.decode_first_stage(latents)
42
+ wave = runner.vae.decode_to_waveform(mel)[0][:audio_len]
43
+ outpath = f"output.wav"
44
+ sf.write(outpath, wave, samplerate=16000, subtype='PCM_16')
45
+ return outpath
46
+
47
+ def preprocess(caption):
48
+ output = preprocess_gemini(caption)
49
+ return output, output
50
+
51
+ with gr.Blocks() as demo:
52
+ with gr.Row():
53
+ gr.Markdown("## PicoAudio")
54
+ with gr.Row():
55
+ description_text = f"18 events: {', '.join(event_list)}"
56
+ gr.Markdown(description_text)
57
+
58
+ with gr.Row():
59
+ gr.Markdown("## Step1")
60
+ with gr.Row():
61
+ preprocess_description_text = f"preprocess: free-text to timestamp caption via LLM"
62
+ gr.Markdown(preprocess_description_text)
63
+ with gr.Row():
64
+ with gr.Column():
65
+ freetext_prompt = gr.Textbox(label="Prompt: Input your free-text caption here. (e.g. a dog barks three times.)",
66
+ value="a dog barks three times.",)
67
+ preprocess_run_button = gr.Button()
68
+ prompt = None
69
+ with gr.Column():
70
+ freetext_prompt_out = gr.Textbox(label="Preprocess output")
71
+ with gr.Row():
72
+ with gr.Column():
73
+ gr.Examples(
74
+ examples = [["spraying two times then gunshot three times."],
75
+ ["a dog barks three times."],
76
+ ["cow mooing two times."],],
77
+ inputs = [freetext_prompt],
78
+ outputs = [prompt]
79
+ )
80
+ with gr.Column():
81
+ pass
82
+
83
+
84
+ with gr.Row():
85
+ gr.Markdown("## Step2")
86
+ with gr.Row():
87
+ with gr.Column():
88
+ prompt = gr.Textbox(label="Prompt: Input your caption formatted as 'event1 at onset1-offset1_onset2-offset2 and event2 at onset1-offset1'.",
89
+ value="spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031.",)
90
+ generate_run_button = gr.Button()
91
+ with gr.Accordion("Advanced options", open=False):
92
+ num_steps = gr.Slider(label="num_steps", minimum=1, maximum=300, value=200, step=1)
93
+ guidance_scale = gr.Slider(label="guidance_scale", minimum=0.1, maximum=8.0, value=3.0, step=0.1)
94
+ with gr.Column():
95
+ outaudio = gr.Audio()
96
+ preprocess_run_button.click(fn=preprocess_gemini, inputs=[freetext_prompt], outputs=[prompt, freetext_prompt_out])
97
+ generate_run_button.click(fn=infer, inputs=[prompt, num_steps, guidance_scale], outputs=[outaudio])
98
+
99
+ with gr.Row():
100
+ with gr.Column():
101
+ gr.Examples(
102
+ examples = [["spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031."],
103
+ ["dog_barking at 0.562-2.562_4.25-6.25."],
104
+ ["cow_mooing at 0.958-3.582_5.272-7.896."],],
105
+ inputs = [prompt, num_steps, guidance_scale],
106
+ outputs = [outaudio]
107
+ )
108
+ with gr.Column():
109
+ pass
110
+
111
+
112
+ demo.launch()
113
+
114
+
115
+ # description_text = f"18 events: {', '.join(event_list)}"
116
+ # prompt = gr.Textbox(label="Prompt: Input your caption formatted as 'event1 at onset1-offset1_onset2-offset2 and event2 at onset1-offset1'.",
117
+ # value="spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031.",)
118
+ # outaudio = gr.Audio()
119
+ # num_steps = gr.Slider(label="num_steps", minimum=1, maximum=300, value=200, step=1)
120
+ # guidance_scale = gr.Slider(label="guidance_scale", minimum=0.1, maximum=8.0, value=3.0, step=0.1)
121
+ # gr_interface = gr.Interface(
122
+ # fn=infer,
123
+ # inputs=[prompt, num_steps, guidance_scale],
124
+ # outputs=[outaudio],
125
+ # title="PicoAudio",
126
+ # description=description_text,
127
+ # allow_flagging=False,
128
+ # examples=[
129
+ # ["spraying at 0.38-1.176_3.06-3.856 and gunshot at 1.729-3.729_4.367-6.367_7.031-9.031."],
130
+ # ["dog_barking at 0.562-2.562_4.25-6.25."],
131
+ # ["cow_mooing at 0.958-3.582_5.272-7.896."],
132
+ # ],
133
+ # cache_examples="lazy", # Turn on to cache.
134
+ # )
135
+ # gr_interface.queue(10).launch()
data/train_multi-event_v3.json ADDED
The diff for this file is too large to render. See raw diff
 
data/train_single-event_multi_v3.json ADDED
The diff for this file is too large to render. See raw diff
 
data/train_single-event_single_v3.json ADDED
The diff for this file is too large to render. See raw diff
 
llm_preprocess.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ At the command line, only need to run once to install the package via pip:
3
+
4
+ $ pip install google-generativeai
5
+ """
6
+
7
+ from pathlib import Path
8
+ import os
9
+ import json
10
+ import re
11
+
12
+ def get_event():
13
+ event_list = [
14
+ "burping_belching", # 0
15
+ "car_horn_honking", #
16
+ "cat_meowing", #
17
+ "cow_mooing", #
18
+ "dog_barking", #
19
+ "door_knocking", #
20
+ "door_slamming", #
21
+ "explosion", #
22
+ "gunshot", # 8
23
+ "sheep_goat_bleating", #
24
+ "sneeze", #
25
+ "spraying", #
26
+ "thump_thud", #
27
+ "train_horn", #
28
+ "tapping_clicking_clanking", #
29
+ "woman_laughing", #
30
+ "duck_quacking", # 16
31
+ "whistling", #
32
+ ]
33
+ return event_list
34
+
35
+ def get_prompt():
36
+
37
+ train_json_list = ["data/train_multi-event_v3.json",
38
+ f"data/train_single-event_multi_v3.json",
39
+ f"data/train_single-event_single_v3.json"]
40
+ learn_pair = ""
41
+ for train_json in train_json_list:
42
+ with open(train_json, 'r') as train_file:
43
+ for idx, line in enumerate(train_file):
44
+ if idx >= 300: break
45
+ data = json.loads(line.strip())
46
+ learn_pair += f"{str(idx)}:{data['captions']}~{data['onset']}. "
47
+ preffix_prompt = "You need to convert the input sentence into the following standard timing format: 'event1--event2-- ... --eventN', " +\
48
+ "where the 'eventN' format is 'eventN__onset1-offset1_onset2-offset2_ ... _onsetK-offsetK'. " +\
49
+ "The 'onset-offset' inside needs to be determined based on common sense and the examples I provide, with a duration not less than 1 and not greater than 4. All format 'onsetk-offsetk' should replaced by number. " +\
50
+ "The very strict constraints are that the total duration is less than 10 seconds, meaning all times are less than 10. It is preferred that events do not overlap as much as possible. " +\
51
+ "Now, I will provide you with 300 examples in training set for your learning, each example in the format 'index: input~output'. " +\
52
+ learn_pair +\
53
+ f"You need to map events to 18 given events: {', '.join(get_event())}"
54
+ #print(preffix_prompt)
55
+ return preffix_prompt
56
+
57
+
58
+ def postprocess(caption):
59
+ caption = caption.replace('__', ' at ').replace('--', ' and ')
60
+ return caption
61
+
62
+ def preprocess_gemini(free_text_caption):
63
+ preffix_prompt = get_prompt()
64
+ import google.generativeai as genai
65
+ genai.configure(api_key="AIzaSyDfGKPQtS9qExCfl3bnfxC1rLPzvORz3E4")
66
+
67
+ # Set up the model
68
+ generation_config = {
69
+ "temperature": 1,
70
+ "top_p": 0.95,
71
+ "top_k": 64,
72
+ "max_output_tokens": 8192,
73
+ }
74
+
75
+ model = genai.GenerativeModel(model_name="gemini-1.5-flash",
76
+ generation_config=generation_config,)
77
+
78
+ prompt_parts = [
79
+ preffix_prompt +\
80
+ f"Please convert the following inputs into the standard timing format:{free_text_caption}. You should only output results in the standard timing format. Do not output anything other than format and do not add symbols.",
81
+ ]
82
+
83
+ timestampCaption = model.generate_content(prompt_parts)
84
+
85
+ # output = "dog_barking at 0.562-2.562_4.25-6.25_7.01-8.21."
86
+ return postprocess(timestampCaption)
87
+
88
+ def preprocess_gpt(free_text_caption):
89
+ preffix_prompt = get_prompt()
90
+ from openai import OpenAI
91
+ client = OpenAI(api_key="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")
92
+ completion_start = client.chat.completions.create(
93
+ model="gpt-4-1106-preview",
94
+ messages=[{
95
+ "role": "user",
96
+ "content":
97
+ preffix_prompt +\
98
+ f"Please convert the following inputs into the standard timing format:{free_text_caption}. You should only output results in the standard timing format. Do not output anything other than format and do not add symbols."
99
+ }]
100
+ )
101
+
102
+ timestampCaption = completion_start.choices[0].message.content
103
+ #output = "dog_barking at 0.562-2.562_4.25-6.25_7.01-8.21."
104
+ return postprocess(timestampCaption)
105
+
106
+ if __name__=="__main__":
107
+ caption = preprocess_gemini("spraying two times then gunshot three times.")
108
+ print(caption)
pico_model.py CHANGED
@@ -10,6 +10,37 @@ from diffusers import DDPMScheduler, UNet2DConditionModel
10
 
11
  from audioldm.audio.stft import TacotronSTFT
12
  from audioldm.variational_autoencoder.autoencoder import AutoencoderKL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def _init_layer(layer):
15
  """Initialize a Linear or Convolutional layer. """
@@ -229,7 +260,7 @@ class PicoDiffusion(ClapText_Onset_2_Audio_Diffusion):
229
  ckpt = clap_load_state_dict(freeze_text_encoder_ckpt, skip_params=True)
230
  del_parameter_key = ["text_branch.embeddings.position_ids"]
231
  ckpt = {f"freeze_text_encoder.model.{k}":v for k, v in ckpt.items() if k not in del_parameter_key}
232
- diffusion_ckpt = torch.load(diffusion_pt, map_location=torch.device(self.device))
233
  del diffusion_ckpt["class_emb.weight"]
234
  ckpt.update(diffusion_ckpt)
235
  self.load_state_dict(ckpt)
 
10
 
11
  from audioldm.audio.stft import TacotronSTFT
12
  from audioldm.variational_autoencoder.autoencoder import AutoencoderKL
13
+ from audioldm.utils import default_audioldm_config, get_metadata
14
+
15
+
16
+
17
+ def build_pretrained_models(name):
18
+ checkpoint = torch.load(get_metadata()[name]["path"], map_location="cpu")
19
+ scale_factor = checkpoint["state_dict"]["scale_factor"].item()
20
+
21
+ vae_state_dict = {k[18:]: v for k, v in checkpoint["state_dict"].items() if "first_stage_model." in k}
22
+
23
+ config = default_audioldm_config(name)
24
+ vae_config = config["model"]["params"]["first_stage_config"]["params"]
25
+ vae_config["scale_factor"] = scale_factor
26
+
27
+ vae = AutoencoderKL(**vae_config)
28
+ vae.load_state_dict(vae_state_dict)
29
+
30
+ fn_STFT = TacotronSTFT(
31
+ config["preprocessing"]["stft"]["filter_length"],
32
+ config["preprocessing"]["stft"]["hop_length"],
33
+ config["preprocessing"]["stft"]["win_length"],
34
+ config["preprocessing"]["mel"]["n_mel_channels"],
35
+ config["preprocessing"]["audio"]["sampling_rate"],
36
+ config["preprocessing"]["mel"]["mel_fmin"],
37
+ config["preprocessing"]["mel"]["mel_fmax"],
38
+ )
39
+
40
+ vae.eval()
41
+ fn_STFT.eval()
42
+
43
+ return vae, fn_STFT
44
 
45
  def _init_layer(layer):
46
  """Initialize a Linear or Convolutional layer. """
 
260
  ckpt = clap_load_state_dict(freeze_text_encoder_ckpt, skip_params=True)
261
  del_parameter_key = ["text_branch.embeddings.position_ids"]
262
  ckpt = {f"freeze_text_encoder.model.{k}":v for k, v in ckpt.items() if k not in del_parameter_key}
263
+ diffusion_ckpt = torch.load(diffusion_pt)
264
  del diffusion_ckpt["class_emb.weight"]
265
  ckpt.update(diffusion_ckpt)
266
  self.load_state_dict(ckpt)
requirements.txt CHANGED
@@ -1,29 +1,30 @@
1
- torch==2.0.1
2
- torchaudio==2.0.2
3
- torchvision==0.15.2
4
- transformers==4.37.2
5
- accelerate==0.26.1
6
- datasets==2.16.1
7
- diffusers==0.18.2
8
- einops==0.7.0
9
- h5py==3.10.0
10
- huggingface_hub==0.20.3
11
- importlib_metadata==7.0.1
12
- librosa==0.10.1
13
- matplotlib==3.8.2
14
- numpy==1.23.5
15
- omegaconf==2.0.6
16
- packaging==23.2
17
- pandas==2.2.0
18
- progressbar33==2.4
19
- protobuf==3.20.*
20
- resampy==0.4.2
21
- scikit_image==0.22.0
22
- scikit_learn==1.4.0
23
- scipy==1.12.0
24
- soundfile==0.12.1
25
- ssr_eval==0.0.7
26
- torchlibrosa==0.1.0
27
- tqdm==4.63.1
28
- laion-clap==1.1.4
29
- gradio
 
 
1
+ torch==2.0.1
2
+ torchaudio==2.0.2
3
+ torchvision==0.15.2
4
+ transformers==4.37.2
5
+ accelerate==0.26.1
6
+ datasets==2.16.1
7
+ diffusers==0.18.2
8
+ einops==0.7.0
9
+ h5py==3.10.0
10
+ huggingface_hub==0.20.3
11
+ importlib_metadata==7.0.1
12
+ librosa==0.10.1
13
+ matplotlib==3.8.2
14
+ numpy==1.23.5
15
+ omegaconf==2.0.6
16
+ packaging==23.2
17
+ pandas==2.2.0
18
+ progressbar33==2.4
19
+ protobuf==3.20.*
20
+ resampy==0.4.2
21
+ scikit_image==0.22.0
22
+ scikit_learn==1.4.0
23
+ scipy==1.12.0
24
+ soundfile==0.12.1
25
+ ssr_eval==0.0.7
26
+ torchlibrosa==0.1.0
27
+ tqdm==4.63.1
28
+ laion-clap==1.1.4
29
+ gradio
30
+ google-generativeai