diff --git a/app.py b/app.py index 547b6ff5cc070f4f903a46954c1e72f602b8cd58..03558bc631c27f8227caa6df2cf6aad9fe43d11b 100644 --- a/app.py +++ b/app.py @@ -17,8 +17,13 @@ except ImportError: func = args[0] return func +import os +import shutil import tempfile import threading +import time +import urllib.request +from pathlib import Path import gradio as gr import soundfile as sf @@ -29,6 +34,31 @@ import picogen2 from picogen2.mirtoolkit.beat_this import BeatThis from picogen2.mirtoolkit.sheetsage import SheetSage +REPO_ROOT = Path(__file__).parent + + +def _download_with_progress(url: str, dest: Path, label: str, interval_s: float = 20.0): + """Downloads url to dest, logging progress at most once per interval_s.""" + if dest.exists(): + return + dest.parent.mkdir(parents=True, exist_ok=True) + tmp_path = dest.with_name(dest.name + ".part") + with urllib.request.urlopen(url) as response, open(tmp_path, "wb") as f: + total = int(response.headers.get("Content-Length", 0)) + downloaded = 0 + last_log = time.monotonic() + while chunk := response.read(1024 * 1024): + f.write(chunk) + downloaded += len(chunk) + now = time.monotonic() + if now - last_log >= interval_s: + pct = 100 * downloaded / total if total else 0 + print(f"{label}: {downloaded / 1e9:.2f}/{total / 1e9:.2f}GB ({pct:.0f}%)") + last_log = now + tmp_path.rename(dest) + print(f"{label}: done ({dest.stat().st_size / 1e9:.2f}GB)") + + # SheetSage (this model's audio feature extractor) was trained on ~24s segments and is # most accurate on short clips; longer songs also risk exceeding the GPU time budget below. MAX_INPUT_SECONDS = 30.0 @@ -46,25 +76,49 @@ model_error = None def load_assets(): - """Downloads PiCoGen2's checkpoint, pre-fetches SheetSage's (large) asset cache, and - builds the beat tracker, all on CPU so the app can start serving while this runs.""" + """Downloads PiCoGen2's checkpoint and Jukebox's weights, stages SheetSage's vendored + checkpoints, and builds the beat tracker -- all on CPU so the app can start serving + while this runs.""" global decoder, tokenizer, beat_detector, model_loading, model_error try: tokenizer = picogen2.Tokenizer() decoder = picogen2.PiCoGenDecoder.from_pretrained(device="cpu") - try: - import sheetsage.assets as sheetsage_assets - - for tag in sheetsage_assets.get_asset_tags(): - sheetsage_assets.retrieve_asset(tag) - except Exception as e: - # SheetSage lazily re-downloads whatever's missing on first use, so this is - # a warm-up, not a hard requirement. - print(f"SheetSage asset pre-fetch incomplete, will retry on first request: {e}") + # SheetSage's upstream S3 bucket (its own retrieve_asset download source) has + # been dead for a while (see https://github.com/chrisdonahue/sheetsage/issues/44, + # 45, 46). Its checkpoints are small (245MB total) and vendored directly in this + # repo instead; stage them where sheetsage.assets.retrieve_asset expects to find + # them so it treats them as already downloaded. + sheetsage_cache = Path.home() / ".sheetsage" / "sheetsage" / "v0.2" + sheetsage_cache.mkdir(parents=True, exist_ok=True) + for item in (REPO_ROOT / "sheetsage" / "weights").iterdir(): + dest = sheetsage_cache / item.name + if item.name.startswith(".") or dest.exists(): + continue + if item.is_dir(): + shutil.copytree(item, dest) + else: + shutil.copy(item, dest) + + # Jukebox's own weights are hosted on OpenAI's CDN, unrelated to (and unaffected + # by) SheetSage's dead bucket. Same default cache path jukebox's own downloader + # uses (see jukebox/make_models.py:load_checkpoint), pre-fetched here so the + # first real request doesn't have to wait on a 10GB download inside its GPU + # time budget. + jukebox_cache = Path(os.environ.get("JUKEBOX_CACHE_DIR", "~/.cache")).expanduser() + _download_with_progress( + "https://openaipublic.azureedge.net/jukebox/models/5b/vqvae.pth.tar", + jukebox_cache / "jukebox" / "models" / "5b" / "vqvae.pth.tar", + "jukebox vqvae", + ) + _download_with_progress( + "https://openaipublic.azureedge.net/jukebox/models/5b/prior_level_2.pth.tar", + jukebox_cache / "jukebox" / "models" / "5b" / "prior_level_2.pth.tar", + "jukebox prior_level_2", + ) beat_detector = BeatThis(cuda=False) - print("Models loaded (CPU).") + print("Models loaded (CPU); Jukebox weights ready.") except Exception as e: model_error = str(e) print(f"Load error: {e}") diff --git a/constraints.txt b/constraints.txt deleted file mode 100644 index b722ef6295b56f0fc63537c4e716260a0d0b8e68..0000000000000000000000000000000000000000 --- a/constraints.txt +++ /dev/null @@ -1 +0,0 @@ -setuptools<82 diff --git a/jukebox/__init__.py b/jukebox/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/align.py b/jukebox/align.py new file mode 100644 index 0000000000000000000000000000000000000000..8084b9739ae0ee26d4c01050c3db4ee84a58db73 --- /dev/null +++ b/jukebox/align.py @@ -0,0 +1,115 @@ +""" +Get alignment from attn values +1. run a forward pass on each hop, get attn values +2. concat for all hops +""" +import numpy as np +import torch as t +from jukebox.utils.torch_utils import assert_shape, empty_cache +from jukebox.hparams import Hyperparams +from jukebox.make_models import make_model +from jukebox.save_html import save_html +from jukebox.utils.sample_utils import get_starts +import fire + +def get_alignment(x, zs, labels, prior, fp16, hps): + level = hps.levels - 1 # Top level used + n_ctx, n_tokens = prior.n_ctx, prior.n_tokens + z = zs[level] + bs, total_length = z.shape[0], z.shape[1] + if total_length < n_ctx: + padding_length = n_ctx - total_length + z = t.cat([z, t.zeros(bs, n_ctx - total_length, dtype=z.dtype, device=z.device)], dim=1) + total_length = z.shape[1] + else: + padding_length = 0 + + hop_length = int(hps.hop_fraction[level]*prior.n_ctx) + n_head = prior.prior.transformer.n_head + alignment_head, alignment_layer = prior.alignment_head, prior.alignment_layer + attn_layers = set([alignment_layer]) + alignment_hops = {} + indices_hops = {} + + prior.cuda() + empty_cache() + for start in get_starts(total_length, n_ctx, hop_length): + end = start + n_ctx + + # set y offset, sample_length and lyrics tokens + y, indices_hop = prior.get_y(labels, start, get_indices=True) + assert len(indices_hop) == bs + for indices in indices_hop: + assert len(indices) == n_tokens + + z_bs = t.chunk(z, bs, dim=0) + y_bs = t.chunk(y, bs, dim=0) + w_hops = [] + for z_i, y_i in zip(z_bs, y_bs): + w_hop = prior.z_forward(z_i[:,start:end], [], y_i, fp16=fp16, get_attn_weights=attn_layers) + assert len(w_hop) == 1 + w_hops.append(w_hop[0][:, alignment_head]) + del w_hop + w = t.cat(w_hops, dim=0) + del w_hops + assert_shape(w, (bs, n_ctx, n_tokens)) + alignment_hop = w.float().cpu().numpy() + assert_shape(alignment_hop, (bs, n_ctx, n_tokens)) + del w + + # alignment_hop has shape (bs, n_ctx, n_tokens) + # indices_hop is a list of len=bs, each entry of len hps.n_tokens + indices_hops[start] = indices_hop + alignment_hops[start] = alignment_hop + prior.cpu() + empty_cache() + + # Combine attn for each hop into attn for full range + # Use indices to place them into correct place for corresponding source tokens + alignments = [] + for item in range(bs): + # Note each item has different length lyrics + full_tokens = labels['info'][item]['full_tokens'] + alignment = np.zeros((total_length, len(full_tokens) + 1)) + for start in reversed(get_starts(total_length, n_ctx, hop_length)): + end = start + n_ctx + alignment_hop = alignment_hops[start][item] + indices = indices_hops[start][item] + assert len(indices) == n_tokens + assert alignment_hop.shape == (n_ctx, n_tokens) + alignment[start:end,indices] = alignment_hop + alignment = alignment[:total_length - padding_length,:-1] # remove token padding, and last lyric index + alignments.append(alignment) + return alignments + +def save_alignment(model, device, hps): + print(hps) + vqvae, priors = make_model(model, device, hps, levels=[-1]) + + logdir = f"{hps.logdir}/level_{0}" + data = t.load(f"{logdir}/data.pth.tar") + if model == '1b_lyrics': + fp16 = False + else: + fp16 = True + + data['alignments'] = get_alignment(data['x'], data['zs'], data['labels'][-1], priors[-1], fp16, hps) + t.save(data, f"{logdir}/data_align.pth.tar") + save_html(logdir, data['x'], data['zs'], data['labels'][-1], data['alignments'], hps) + +def run(model, port=29500, **kwargs): + from jukebox.utils.dist_utils import setup_dist_from_mpi + rank, local_rank, device = setup_dist_from_mpi(port=port) + hps = Hyperparams(**kwargs) + + with t.no_grad(): + save_alignment(model, device, hps) + +if __name__ == '__main__': + fire.Fire(run) + + + + + + diff --git a/jukebox/data/__init__.py b/jukebox/data/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/data/artist_genre_processor.py b/jukebox/data/artist_genre_processor.py new file mode 100644 index 0000000000000000000000000000000000000000..be82ef9aad926f4a44776a6784d60babd02f9551 --- /dev/null +++ b/jukebox/data/artist_genre_processor.py @@ -0,0 +1,93 @@ +import os +import re + +accepted = frozenset([chr(i) for i in range(ord('a'), ord('z') + 1)] + + [chr(i) for i in range(ord('A'), ord('Z') + 1)] + + [chr(i) for i in range(ord('0'), ord('9') + 1)]) + +rex = re.compile(r'_+') + +def norm(s): + s = ''.join([c if c in accepted else '_' for c in s.lower()]) + s = rex.sub('_', s).strip('_') + return s + +def create_reverse_lookup(atoi): + # Multiple entries could go to the same artist_id/genre_id + itoa = {} + for a, i in atoi.items(): + if i not in itoa: + itoa[i] = [] + itoa[i].append(a) + indices = sorted(list(itoa.keys())) + for i in indices: + itoa[i] = '_'.join(sorted(itoa[i])) + return itoa + +class ArtistGenreProcessor(): + def __init__(self, v3=False): + self.v3 = v3 + dirname = os.path.dirname(__file__) + if self.v3: + self.artist_id_file = f"{dirname}/ids/v3_artist_ids.txt" + self.genre_id_file = f"{dirname}/ids/v3_genre_ids.txt" + else: + self.artist_id_file = f"{dirname}/ids/v2_artist_ids.txt" + self.genre_id_file = f"{dirname}/ids/v2_genre_ids.txt" + self.load_artists() + self.load_genres() + + def get_artist_id(self, artist): + input_artist = artist + if self.v3: + artist = artist.lower() + else: + artist = norm(artist) + if artist not in self.artist_ids: + print(f"Input artist {input_artist} maps to {artist}, which is not present in {self.artist_id_file}. " + f"Defaulting to (artist_id, artist) = (0, unknown), if that seems wrong please format artist correctly") + return self.artist_ids.get(artist, 0) + + def get_genre_ids(self, genre): + if self.v3: + genres = [genre.lower()] + else: + # In v2, we convert genre into a bag of words + genres = norm(genre).split("_") + for word in genres: + if word not in self.genre_ids: + print(f"Input genre {genre} maps to the list {genres}. {word} is not present in {self.genre_id_file}. " + f"Defaulting to (word_id, word) = (0, unknown), if that seems wrong please format genre correctly") + return [self.genre_ids.get(word, 0) for word in genres] + + # get_artist/genre throw error if we ask for non-present values + def get_artist(self, artist_id): + return self.artists[artist_id] + + def get_genre(self, genre_ids): + if self.v3: + assert len(genre_ids) == 1 + genre = self.genres[genre_ids[0]] + else: + genre = '_'.join([self.genres[genre_id] for genre_id in genre_ids if genre_id >= 0]) + return genre + + def load_artists(self): + print(f'Loading artist IDs from {self.artist_id_file}') + self.artist_ids = {} + with open(self.artist_id_file, 'r', encoding="utf-8") as f: + for line in f: + artist, artist_id = line.strip().split(';') + self.artist_ids[artist.lower()] = int(artist_id) + self.artists = create_reverse_lookup(self.artist_ids) + + def load_genres(self): + print(f'Loading artist IDs from {self.genre_id_file}') + self.genre_ids = {} + with open(self.genre_id_file, 'r', encoding="utf-8") as f: + for line in f: + genre, genre_id = line.strip().split(';') + self.genre_ids[genre.lower()] = int(genre_id) + self.genres = create_reverse_lookup(self.genre_ids) + + diff --git a/jukebox/data/data_processor.py b/jukebox/data/data_processor.py new file mode 100644 index 0000000000000000000000000000000000000000..9a1924c5a7e4ed1ea4017dfec6de10bb5644791e --- /dev/null +++ b/jukebox/data/data_processor.py @@ -0,0 +1,69 @@ +import torch as t +import jukebox.utils.dist_adapter as dist +from torch.utils.data.distributed import DistributedSampler +from torch.utils.data import DataLoader, Dataset, BatchSampler, RandomSampler +from jukebox.utils.dist_utils import print_all +from jukebox.utils.audio_utils import calculate_bandwidth +from jukebox.data.files_dataset import FilesAudioDataset + +class OffsetDataset(Dataset): + def __init__(self, dataset, start, end, test=False): + super().__init__() + self.dataset = dataset + self.start = start + self.end = end + self.test = test + assert 0 <= self.start < self.end <= len(self.dataset) + + def __len__(self): + return self.end - self.start + + def __getitem__(self, item): + return self.dataset.get_item(self.start + item, test=self.test) + +class DataProcessor(): + def __init__(self, hps): + self.dataset = FilesAudioDataset(hps) + duration = 1 if hps.prior else 600 + hps.bandwidth = calculate_bandwidth(self.dataset, hps, duration=duration) + self.create_datasets(hps) + self.create_samplers(hps) + self.create_data_loaders(hps) + self.print_stats(hps) + + def set_epoch(self, epoch): + self.train_sampler.set_epoch(epoch) + self.test_sampler.set_epoch(epoch) + + def create_datasets(self, hps): + train_len = int(len(self.dataset) * hps.train_test_split) + self.train_dataset = OffsetDataset(self.dataset, 0, train_len, test=False) + self.test_dataset = OffsetDataset(self.dataset, train_len, len(self.dataset), test=True) + + def create_samplers(self, hps): + if not dist.is_available(): + self.train_sampler = BatchSampler(RandomSampler(self.train_dataset), batch_size=hps.bs, drop_last=True) + self.test_sampler = BatchSampler(RandomSampler(self.test_dataset), batch_size=hps.bs, drop_last=True) + else: + self.train_sampler = DistributedSampler(self.train_dataset) + self.test_sampler = DistributedSampler(self.test_dataset) + + def create_data_loaders(self, hps): + # Loader to load mini-batches + if hps.labels: + collate_fn = lambda batch: tuple(t.stack([t.from_numpy(b[i]) for b in batch], 0) for i in range(2)) + else: + collate_fn = lambda batch: t.stack([t.from_numpy(b) for b in batch], 0) + + print('Creating Data Loader') + self.train_loader = DataLoader(self.train_dataset, batch_size=hps.bs, num_workers=hps.nworkers, + sampler=self.train_sampler, pin_memory=False, + drop_last=True, collate_fn=collate_fn) + self.test_loader = DataLoader(self.test_dataset, batch_size=hps.bs, num_workers=hps.nworkers, + sampler=self.test_sampler, pin_memory=False, + drop_last=False, collate_fn=collate_fn) + + def print_stats(self, hps): + print_all(f"Train {len(self.train_dataset)} samples. Test {len(self.test_dataset)} samples") + print_all(f'Train sampler: {self.train_sampler}') + print_all(f'Train loader: {len(self.train_loader)}') diff --git a/jukebox/data/files_dataset.py b/jukebox/data/files_dataset.py new file mode 100644 index 0000000000000000000000000000000000000000..68d5408f4007353aa57a2cec8a425f9d92ea7e72 --- /dev/null +++ b/jukebox/data/files_dataset.py @@ -0,0 +1,99 @@ +import librosa +import math +import numpy as np +import jukebox.utils.dist_adapter as dist +from torch.utils.data import Dataset +from jukebox.utils.dist_utils import print_all +from jukebox.utils.io import get_duration_sec, load_audio +from jukebox.data.labels import Labeller + +class FilesAudioDataset(Dataset): + def __init__(self, hps): + super().__init__() + self.sr = hps.sr + self.channels = hps.channels + self.min_duration = hps.min_duration or math.ceil(hps.sample_length / hps.sr) + self.max_duration = hps.max_duration or math.inf + self.sample_length = hps.sample_length + assert hps.sample_length / hps.sr < self.min_duration, f'Sample length {hps.sample_length} per sr {hps.sr} ({hps.sample_length / hps.sr:.2f}) should be shorter than min duration {self.min_duration}' + self.aug_shift = hps.aug_shift + self.labels = hps.labels + self.init_dataset(hps) + + def filter(self, files, durations): + # Remove files too short or too long + keep = [] + for i in range(len(files)): + if durations[i] / self.sr < self.min_duration: + continue + if durations[i] / self.sr >= self.max_duration: + continue + keep.append(i) + print_all(f'self.sr={self.sr}, min: {self.min_duration}, max: {self.max_duration}') + print_all(f"Keeping {len(keep)} of {len(files)} files") + self.files = [files[i] for i in keep] + self.durations = [int(durations[i]) for i in keep] + self.cumsum = np.cumsum(self.durations) + + def init_dataset(self, hps): + # Load list of files and starts/durations + files = librosa.util.find_files(f'{hps.audio_files_dir}', ['mp3', 'opus', 'm4a', 'aac', 'wav']) + print_all(f"Found {len(files)} files. Getting durations") + cache = dist.get_rank() % 8 == 0 if dist.is_available() else True + durations = np.array([get_duration_sec(file, cache=cache) * self.sr for file in files]) # Could be approximate + self.filter(files, durations) + + if self.labels: + self.labeller = Labeller(hps.max_bow_genre_size, hps.n_tokens, self.sample_length, v3=hps.labels_v3) + + def get_index_offset(self, item): + # For a given dataset item and shift, return song index and offset within song + half_interval = self.sample_length//2 + shift = np.random.randint(-half_interval, half_interval) if self.aug_shift else 0 + offset = item * self.sample_length + shift # Note we centred shifts, so adding now + midpoint = offset + half_interval + assert 0 <= midpoint < self.cumsum[-1], f'Midpoint {midpoint} of item beyond total length {self.cumsum[-1]}' + index = np.searchsorted(self.cumsum, midpoint) # index <-> midpoint of interval lies in this song + start, end = self.cumsum[index - 1] if index > 0 else 0.0, self.cumsum[index] # start and end of current song + assert start <= midpoint <= end, f"Midpoint {midpoint} not inside interval [{start}, {end}] for index {index}" + if offset > end - self.sample_length: # Going over song + offset = max(start, offset - half_interval) # Now should fit + elif offset < start: # Going under song + offset = min(end - self.sample_length, offset + half_interval) # Now should fit + assert start <= offset <= end - self.sample_length, f"Offset {offset} not in [{start}, {end - self.sample_length}]. End: {end}, SL: {self.sample_length}, Index: {index}" + offset = offset - start + return index, offset + + def get_metadata(self, filename, test): + """ + Insert metadata loading code for your dataset here. + If artist/genre labels are different from provided artist/genre lists, + update labeller accordingly. + + Returns: + (artist, genre, full_lyrics) of type (str, str, str). For + example, ("unknown", "classical", "") could be a metadata for a + piano piece. + """ + return None, None, None + + def get_song_chunk(self, index, offset, test=False): + filename, total_length = self.files[index], self.durations[index] + data, sr = load_audio(filename, sr=self.sr, offset=offset, duration=self.sample_length) + assert data.shape == (self.channels, self.sample_length), f'Expected {(self.channels, self.sample_length)}, got {data.shape}' + if self.labels: + artist, genre, lyrics = self.get_metadata(filename, test) + labels = self.labeller.get_label(artist, genre, lyrics, total_length, offset) + return data.T, labels['y'] + else: + return data.T + + def get_item(self, item, test=False): + index, offset = self.get_index_offset(item) + return self.get_song_chunk(index, offset, test) + + def __len__(self): + return int(np.floor(self.cumsum[-1] / self.sample_length)) + + def __getitem__(self, item): + return self.get_item(item) diff --git a/jukebox/data/ids/v2_artist_ids.txt b/jukebox/data/ids/v2_artist_ids.txt new file mode 100644 index 0000000000000000000000000000000000000000..67db1b0772560abd5fd01e0f6eb87ce14e184cd2 --- /dev/null +++ b/jukebox/data/ids/v2_artist_ids.txt @@ -0,0 +1,4111 @@ +unknown;0 +various;0 +;0 +andr_s_schiff;1 +sonny_terry;2 +nelly;3 +markus_schulz;4 +modest_petrovich_mussorgsky;5 +otis_redding;6 +aerosmith;7 +kenny_g;8 +james_taylor;9 +bobby_bland;10 +burning_spear;11 +skip_james;12 +heart;13 +tammy_wynette;14 +muse;15 +beres_hammond;16 +james_newton_howard;17 +nelson_freire;18 +benny_goodman;19 +hank_williams;20 +they_might_be_giants;21 +the_brian_jonestown_massacre;22 +lady_gaga;23 +chris_young;24 +alison_krauss_union_station;25 +seal;26 +the_hollies;27 +shabba_ranks;28 +paul_young;29 +iration;30 +buck_owens;31 +the_weeknd;32 +elton_john;33 +smokey_robinson;34 +roy_orbison;35 +headhunterz;36 +blondie;37 +the_temptations;38 +ray_stevens;39 +foo_fighters;40 +christoph_eschenbach;41 +blind_willie_mctell;42 +al_martino;43 +edwin_fischer;44 +victor_young;45 +justin_bieber;46 +styx;47 +doris_day;48 +tex_beneke;49 +the_monkees;50 +richard_wagner;51 +bryan_adams;52 +alessandro_scarlatti;53 +rebelution;54 +pitbull;55 +nat_king_cole;56 +wiz_khalifa;57 +roger_miller;58 +andy_williams;59 +peggy_lee;60 +pyotr_ilyich_tchaikovsky;61 +booker_t_the_mg_s;62 +cilla_black;63 +billy_fury;64 +vera_lynn;65 +enrico_caruso;66 +sly_and_robbie;67 +the_pretenders;68 +the_sweet;69 +kylie_minogue;70 +kay_kyser;71 +san_francisco_symphony;72 +prince;73 +queen;74 +kool_the_gang;75 +horace_andy;76 +midnite;77 +gentleman;78 +wilhelm_kempff;79 +busta_rhymes;80 +the_pogues;81 +def_leppard;82 +al_jolson;83 +king_tubby;84 +hot_chocolate;85 +delroy_wilson;86 +jody_watley;87 +bobby_vee;88 +johnny_mathis;89 +the_rascals;90 +sviatoslav_richter;91 +fred_astaire;92 +john_holt;93 +amy_grant;94 +b_b_king;95 +paul_weston;96 +four_tops;97 +jay_sean;98 +pat_boone;99 +george_frideric_handel;100 +bing_crosby;101 +shalamar;102 +tommy_dorsey;103 +ludacris;104 +kenny_chesney;105 +murray_perahia;106 +lightnin_hopkins;107 +ricky_nelson;108 +clint_mansell;109 +tom_petty_and_the_heartbreakers;110 +gary_glitter;111 +ringo_starr;112 +phil_collins;113 +leo_reisman;114 +al_green;115 +jim_reeves;116 +chris_brown;117 +cliff_edwards;118 +buddy_guy;119 +angelo_badalamenti;120 +frank_sinatra;121 +santana;122 +the_pussycat_dolls;123 +peaches_herb;124 +radu_lupu;125 +the_whispers;126 +eddy_howard;127 +memphis_slim;128 +henry_mancini;129 +giuseppe_verdi;130 +the_dream;131 +vladimir_sofronitsky;132 +u_roy;133 +ken_boothe;134 +the_kinks;135 +howard_shore;136 +hardwell;137 +lou_reed;138 +calvin_harris;139 +eddy_chen;140 +anne_murray;141 +juice_newton;142 +bee_gees;143 +wilson_pickett;144 +alan_jackson;145 +shirley_bassey;146 +waylon_jennings;147 +destiny_s_child;148 +cab_calloway;149 +johnny_copeland;150 +bright_eyes;151 +trey_songz;152 +neil_sedaka;153 +justin_timberlake;154 +arthur_grumiaux;155 +the_who;156 +the_yardbirds;157 +big_joe_turner;158 +duke_ellington;159 +herb_alpert;160 +laura_branigan;161 +michael_jackson;162 +john_denver;163 +peter_gordon;164 +solomon_cutner;165 +steve_miller_band;166 +don_williams;167 +the_pointer_sisters;168 +metallica;169 +the_ink_spots;170 +kenny_rogers;171 +the_game;172 +gene_krupa;173 +snoop_dogg;174 +j_cole;175 +taylor_dayne;176 +r3hab;177 +guy_lombardo_and_his_royal_canadians;178 +shakin_stevens;179 +tim_mcgraw;180 +olivia_newton_john_john_travolta;181 +the_replacements;182 +beenie_man;183 +diplo;184 +sammy_kaye;185 +don_gibson;186 +shaggy;187 +nina_simone;188 +stone_temple_pilots;189 +ne_yo;190 +huddie_william_ledbetter;191 +jerry_goldsmith;192 +the_bellamy_brothers;193 +winifred_atwell;194 +georg_philipp_telemann;195 +timbaland;196 +the_5th_dimension;197 +dionne_warwick;198 +r_kelly;199 +enrique_iglesias;200 +sting;201 +mikey_dread;202 +yellowman;203 +eddie_kendricks;204 +blur;205 +twista;206 +paul_anka;207 +chris_cornell;208 +a_ha;209 +pet_shop_boys;210 +yo_yo_ma;211 +tom_jones;212 +neil_diamond;213 +vic_damone;214 +paul_oakenfold;215 +jascha_heifetz;216 +t_i_;217 +dinah_washington;218 +vladimir_ashkenazy;219 +leif_ove_andsnes;220 +johnny_cash;221 +basement_jaxx;222 +sonic_youth;223 +the_isley_brothers;224 +jason_aldean;225 +henryk_szeryng;226 +lloyd_price;227 +reba_mcentire;228 +bon_jovi;229 +bed_ich_smetana;230 +donny_osmond;231 +chuck_berry;232 +the_smashing_pumpkins;233 +israel_vibration;234 +stan_kenton;235 +conway_twitty_loretta_lynn;236 +mcfly;237 +r_e_m;238 +morgan_heritage;239 +lil_wayne;240 +garnett_silk;241 +lee_scratch_perry;242 +howlin_wolf;243 +jon_secada;244 +goo_goo_dolls;245 +brian_hyland;246 +abc;247 +clarence_gatemouth_brown;248 +wilson_phillips;249 +atlantic_starr;250 +david_guetta;251 +s_rgio_mendes;252 +fr_d_ric_chopin;253 +robert_palmer;254 +charlie_musselwhite;255 +level_42;256 +peter_andre;257 +the_spinners;258 +erasure;259 +philippe_entremont;260 +leo_jan_ek;261 +the_kingston_trio;262 +ronnie_milsap;263 +pat_benatar;264 +robert_casadesus;265 +t_bone_walker;266 +duran_duran;267 +jerry_reed;268 +franz_liszt;269 +journey;270 +steve_angello;271 +showaddywaddy;272 +tears_for_fears;273 +john_williams;274 +daniel_m_ller_schott;275 +tampa_red;276 +tina_turner;277 +the_beatles;278 +miranda_lambert;279 +howard_jones;280 +reo_speedwagon;281 +lady_antebellum;282 +no_doubt;283 +status_quo;284 +tiffany;285 +billy_eckstine;286 +danny_elfman;287 +jimmy_wakely;288 +ike_tina_turner;289 +george_gershwin;290 +dinah_shore;291 +armin_van_buuren;292 +keith_sweat;293 +beaux_arts_trio;294 +arcangelo_corelli;295 +air_supply;296 +w_w;297 +the_mighty_diamonds;298 +harry_gregson_williams;299 +blind_lemon_jefferson;300 +brook_benton;301 +sizzla;302 +bobby_darin;303 +steely_dan;304 +the_skatalites;305 +dwight_yoakam;306 +clara_haskil;307 +jah_cure;308 +cliff_richard;309 +fabolous;310 +sonny_boy_williamson_ii;311 +tinie_tempah;312 +claude_debussy;313 +jewel;314 +bob_seger;315 +otis_rush;316 +mikhail_pletnev;317 +gene_autry;318 +blind_blake;319 +ethel_waters;320 +jackie_wilson;321 +big_mama_thornton;322 +mary_wells;323 +the_mills_brothers;324 +rage_against_the_machine;325 +barbra_streisand;326 +frank_crumit;327 +the_clash;328 +dion;329 +all_4_one;330 +t_i;331 +orchestral_manoeuvres_in_the_dark;332 +culture;333 +josh_turner;334 +one_direction;335 +the_rolling_stones;336 +half_pint;337 +the_searchers;338 +vangelis;339 +jackson_browne;340 +the_beach_boys;341 +train;342 +prince_buster;343 +tavares;344 +eve;345 +bessie_smith;346 +trace_adkins;347 +bay_city_rollers;348 +david_allan_coe;349 +rascal_flatts;350 +petula_clark;351 +10cc;352 +50_cent;353 +the_oak_ridge_boys;354 +barry_manilow;355 +truls_m_rk;356 +morrissey;357 +gerry_the_pacemakers;358 +kay_starr;359 +alborosie;360 +engelbert_humperdinck;361 +new_order;362 +tony_bennett;363 +stereophonics;364 +jimmy_reed;365 +akon;366 +echo_the_bunnymen;367 +jamiroquai;368 +stevie_ray_vaughan;369 +ben_e_king;370 +cheap_trick;371 +dusty_springfield;372 +mel_tillis;373 +damian_marley;374 +ruth_etting;375 +westlife;376 +diana_ross;377 +the_shirelles;378 +frankie_laine;379 +sarah_vaughan;380 +ray_price;381 +gordon_lightfoot;382 +eddie_cantor;383 +the_byrds;384 +gary_numan;385 +bonnie_tyler;386 +aswad;387 +brownie_mcghee;388 +joshua_bell;389 +manic_street_preachers;390 +mr_vegas;391 +tanya_tucker;392 +marvin_gaye_tammi_terrell;393 +the_staple_singers;394 +ry_cooder;395 +john_mayall;396 +martina_mcbride;397 +anner_bylsma;398 +magic_sam;399 +avril_lavigne;400 +robert_nighthawk;401 +the_coasters;402 +ace_of_base;403 +joseph_szigeti;404 +artie_shaw;405 +big_bill_broonzy;406 +the_ventures;407 +rick_astley;408 +les_paul;409 +leonid_kogan;410 +hall_oates;411 +three_dog_night;412 +charley_pride;413 +paul_mccartney;414 +alfred_cortot;415 +crystal_gayle;416 +taj_mahal;417 +mary_j_blige;418 +leann_rimes;419 +mildred_bailey;420 +ll_cool_j;421 +lobo;422 +blake_shelton;423 +matt_haimovitz;424 +beastie_boys;425 +johannes_brahms;426 +martha_and_the_vandellas;427 +lou_rawls;428 +the_righteous_brothers;429 +rosalyn_tureck;430 +vince_gill;431 +gary_moore;432 +bad_company;433 +marty_robbins;434 +russ_morgan;435 +david_cassidy;436 +dj_khaled;437 +leonard_pennario;438 +glenn_miller;439 +kings_of_leon;440 +afrojack;441 +cyndi_lauper;442 +trisha_yearwood;443 +diamond_rio;444 +patty_loveless;445 +sugar_minott;446 +willie_nelson;447 +thomas_newman;448 +georgia_gibbs;449 +eric_carmen;450 +ricky_skaggs;451 +earth_wind_fire;452 +peter_tosh;453 +joe_bonamassa;454 +lonnie_johnson;455 +missy_elliott;456 +nicki_minaj;457 +luther_allison;458 +grigory_sokolov;459 +luke_bryan;460 +alanis_morissette;461 +tracy_lawrence;462 +sonny_james;463 +brandy;464 +michael_bolton;465 +boswell_sisters;466 +antonio_vivaldi;467 +fritz_kreisler;468 +elvis_costello_the_attractions;469 +woody_herman;470 +korn;471 +hans_zimmer;472 +the_osmonds;473 +electric_light_orchestra;474 +t_rex;475 +van_cliburn;476 +harry_james;477 +glee_cast;478 +simple_minds;479 +abba;480 +the_jam;481 +tanya_stephens;482 +the_statler_brothers;483 +craig_david;484 +moby;485 +xxxtentacion;486 +paul_simon;487 +magic_slim;488 +natasha_bedingfield;489 +ennio_morricone;490 +carpenters;491 +joe_tex;492 +cocoa_tea;493 +the_glee_cast;494 +martha_argerich;495 +charlie_rich;496 +memphis_minnie;497 +sheryl_crow;498 +jan_dean;499 +nick_cave_and_the_bad_seeds;500 +del_shannon;501 +lee_greenwood;502 +gary_lewis_the_playboys;503 +marcelle_meyer;504 +count_basie;505 +harold_melvin_the_blue_notes;506 +the_fray;507 +the_prodigy;508 +alicia_keys;509 +conway_twitty;510 +barrington_levy;511 +b_o_b;512 +tritonal;513 +mario_lanza;514 +mac_davis;515 +billy_murray;516 +igor_stravinsky;517 +pretenders;518 +jordin_sparks;519 +alice_in_chains;520 +ohio_players;521 +rick_springfield;522 +jimmie_rodgers;523 +buju_banton;524 +linda_ronstadt;525 +george_benson;526 +2pac;527 +soulja_boy;528 +the_flaming_lips;529 +ignacy_jan_paderewski;530 +gloria_estefan;531 +ariana_grande;532 +black_uhuru;533 +tony_pastor;534 +sublime;535 +snow_patrol;536 +daft_punk;537 +johnny_winter;538 +robbie_williams;539 +eddie_rabbitt;540 +james_cotton;541 +brad_paisley;542 +manfred_mann;543 +bassnectar;544 +margaret_whiting;545 +sam_cooke;546 +robert_cray;547 +the_beautiful_south;548 +barbara_mandrell;549 +dick_haymes;550 +creedence_clearwater_revival;551 +chic;552 +ray_charles;553 +carter_family;554 +ti_sto;555 +survivor;556 +c_line_dion;557 +sergei_prokofiev;558 +b_la_bart_k;559 +the_congos;560 +yefim_bronfman;561 +laidback_luke;562 +darius_rucker;563 +ray_anthony;564 +incubus;565 +carole_king;566 +james_brown;567 +swv;568 +bruno_mars;569 +aphex_twin;570 +nitty_gritty_dirt_band;571 +gustav_mahler;572 +the_shadows;573 +the_moody_blues;574 +reverend_gary_davis;575 +sia;576 +gaetano_donizetti;577 +earl_hooker;578 +the_commodores;579 +maria_jo_o_pires;580 +eric_donaldson;581 +elmore_james;582 +sean_kingston;583 +don_carlos;584 +linkin_park;585 +jay_the_americans;586 +grand_funk_railroad;587 +jls;588 +frankie_valli;589 +lefty_frizzell;590 +en_vogue;591 +the_cure;592 +perry_como;593 +johnny_mercer;594 +stevie_wonder;595 +ernest_tubb;596 +ramin_djawadi;597 +ashanti;598 +rosemary_clooney;599 +anne_sophie_mutter;600 +helen_forrest;601 +augustus_pablo;602 +the_carpenters;603 +claudio_arrau;604 +bob_dylan;605 +joe_simon;606 +culture_club;607 +the_ipana_troubadors;608 +jennifer_lopez;609 +karyn_white;610 +joe;611 +sarah_mclachlan;612 +j_geils_band;613 +dean_martin;614 +hank_snow;615 +clyde_mcphatter;616 +tlc;617 +beck;618 +jimmy_dean;619 +roy_acuff;620 +outkast;621 +freddie_mcgregor;622 +gus_arnheim;623 +gramatik;624 +merle_haggard;625 +steve_lawrence;626 +ma_rainey;627 +jimmy_dorsey;628 +johnny_paycheck;629 +arthur_rubinstein;630 +talking_heads;631 +capleton;632 +les_brown;633 +leonard_bernstein;634 +bobby_goldsboro;635 +kendrick_lamar;636 +lenny_kravitz;637 +nat_shilkret;638 +toby_keith;639 +junior_wells;640 +billy_j_kramer_the_dakotas;641 +peter_paul_mary;642 +armand_van_helden;643 +h_sker_d_;644 +alabama;645 +eminem;646 +felix_mendelssohn_bartholdy;647 +richard_goode;648 +pink_floyd;649 +sara_evans;650 +lonnie_donegan;651 +boney_m;652 +deadmau5;653 +lee_ann_womack;654 +eric_clapton;655 +ray_parker_jr;656 +etta_james;657 +the_white_stripes;658 +gary_u_s_bonds;659 +glen_gray_and_the_casa_loma_orchestra;660 +bonnie_raitt;661 +soulja_boy_tell_em;662 +bobby_rydell;663 +carly_simon;664 +koko_taylor;665 +gregory_isaacs;666 +red_hot_chili_peppers;667 +josef_suk;668 +clint_black;669 +buddy_clark;670 +tool;671 +pierre_fournier;672 +alice_cooper;673 +lucky_dube;674 +jorge_bolet;675 +don_diablo;676 +r_l_burnside;677 +klaus_badelt;678 +dolly_parton;679 +james_horner;680 +green_day;681 +henry_burr;682 +the_doors;683 +roxette;684 +louis_armstrong;685 +jerry_butler;686 +louis_prima;687 +paul_van_dyk;688 +dennis_brown;689 +toni_braxton;690 +jerry_lee_lewis;691 +donna_summer;692 +percy_faith;693 +willie_dixon;694 +elvis_costello;695 +youri_egorov;696 +dmitri_shostakovich;697 +webb_pierce;698 +monica;699 +pierre_laurent_aimard;700 +muddy_waters;701 +garth_brooks;702 +boyz_ii_men;703 +kris_kristofferson;704 +duane_eddy;705 +coolio;706 +gidon_kremer;707 +eurythmics;708 +randy_travis;709 +collie_buddz;710 +faith_evans;711 +matisyahu;712 +brooks_dunn;713 +lulu;714 +fletcher_henderson;715 +eek_a_mouse;716 +shlomo_mintz;717 +ray_noble;718 +bill_withers;719 +ub40;720 +b_j_thomas;721 +mariah_carey;722 +olivia_newton_john;723 +jackson_5;724 +michael_rose;725 +three_days_grace;726 +glen_campbell;727 +keith_urban;728 +onerepublic;729 +ted_weems;730 +johnny_desmond;731 +billy_preston;732 +billy_vaughn;733 +otis_spann;734 +marion_harris;735 +richard_marx;736 +frankie_carle;737 +xavier_cugat;738 +zz_top;739 +faz_l_say;740 +new_york_philharmonic;741 +teresa_brewer;742 +pixies;743 +david_oistrakh;744 +rory_gallagher;745 +ted_lewis_his_band;746 +patsy_cline;747 +tracy_byrd;748 +daniel_shafran;749 +johnny_horton;750 +billy_ocean;751 +don_mclean;752 +ginuwine;753 +kiss;754 +kaskade;755 +the_hold_steady;756 +rod_stewart;757 +rudolf_serkin;758 +the_wanted;759 +herman_s_hermits;760 +rusty_draper;761 +jay_z;762 +mississippi_john_hurt;763 +linval_thompson;764 +billie_holiday;765 +lawrence_welk;766 +john_lee_hooker;767 +the_offspring;768 +ramones;769 +ronan_keating;770 +sir_clifford_michael_curzon;771 +dierks_bentley;772 +bush;773 +texas;774 +gene_austin;775 +after_all;776 +depeche_mode;777 +eddy_arnold;778 +ferry_corsten;779 +inxs;780 +jimmie_lunceford;781 +johann_sebastian_bach;782 +maxi_priest;783 +travis_tritt;784 +girls_aloud;785 +meat_loaf;786 +brenda_lee;787 +modest_mouse;788 +glenn_gould;789 +mc_hammer;790 +erik_satie;791 +the_andrews_sisters;792 +alicia_de_larrocha;793 +america;794 +charles_harrison;795 +georges_cziffra;796 +peter_serkin;797 +gladys_knight_the_pips;798 +anton_n_dvo_k;799 +emil_gilels;800 +myra_hess;801 +portugal_the_man;802 +rufus;803 +sergei_rachmaninoff;804 +andr_previn;805 +natalie_cole;806 +the_killers;807 +helen_reddy;808 +billy_idol;809 +shawn_mendes;810 +john_lennon;811 +joan_jett;812 +jimmy_cliff;813 +taylor_swift;814 +shura_cherkassky;815 +marvin_gaye;816 +the_drifters;817 +paul_revere_the_raiders;818 +donovan;819 +alma_gluck;820 +fleetwood_mac;821 +jo_stafford;822 +samson_fran_ois;823 +vaughn_monroe;824 +tennessee_ernie_ford;825 +whitesnake;826 +iron_maiden;827 +blind_boy_fuller;828 +eric_church;829 +atomic_kitten;830 +harry_nilsson;831 +paul_specht;832 +bob_marley;833 +les_baxter;834 +aretha_franklin;835 +jessie_j;836 +robert_johnson;837 +maroon_5;838 +sheena_easton;839 +george_strait;840 +bruce_springsteen;841 +oasis;842 +jack_white;843 +fatboy_slim;844 +the_jesus_and_mary_chain;845 +hank_williams_jr;846 +bill_haley_his_comets;847 +charlie_daniels;848 +pearl_jam;849 +the_stylistics;850 +sean_paul;851 +david_essex;852 +zino_francescatti;853 +bruce_hornsby;854 +system_of_a_down;855 +scott_joplin;856 +benny_benassi;857 +mitch_miller;858 +gloria_gaynor;859 +steve_winwood;860 +drake;861 +bone_thugs_n_harmony;862 +nickelback;863 +john_mellencamp;864 +gene_pitney;865 +chet_atkins;866 +mark_ronson;867 +kc_the_sunshine_band;868 +chingy;869 +maurice_ravel;870 +infected_mushroom;871 +walter_gieseking;872 +pavement;873 +deniece_williams;874 +tommy_james_the_shondells;875 +harry_belafonte;876 +robert_schuman;877 +george_jones;878 +whitney_houston;879 +the_ames_brothers;880 +max_romeo;881 +patti_page;882 +p_nk;883 +vienna_philharmonic;884 +violent_femmes;885 +sly_the_family_stone;886 +johnny_marvin;887 +sammy_davis_jr_;888 +nirvana;889 +the_turtles;890 +the_manhattans;891 +the_supremes;892 +gregg_allman;893 +alton_ellis;894 +giacomo_puccini;895 +artur_schnabel;896 +2_unlimited;897 +michael_rabin;898 +toto;899 +lil_kim;900 +shinedown;901 +teddy_wilson;902 +alpha_blondy;903 +the_guess_who;904 +my_chemical_romance;905 +matchbox_twenty;906 +wolfgang_gartner;907 +ed_sheeran;908 +faron_young;909 +fats_waller;910 +kate_smith;911 +loretta_lynn;912 +antonio_meneses;913 +tony_martin;914 +frankie_vaughan;915 +the_mamas_the_papas;916 +david_bowie;917 +erskine_hawkins;918 +the_four_lads;919 +queens_of_the_stone_age;920 +the_human_league;921 +mud;922 +bread;923 +dixie_chicks;924 +backstreet_boys;925 +connie_francis;926 +the_black_keys;927 +paul_weller;928 +pieter_wispelwey;929 +the_bachelors;930 +janet_jackson;931 +the_association;932 +edwin_starr;933 +hank_williams_jr_;934 +steven_isserlis;935 +the_doobie_brothers;936 +jimi_hendrix;937 +sousa_s_band;938 +ricky_martin;939 +the_cranberries;940 +paul_whiteman;941 +the_saturdays;942 +keb_mo;943 +the_psychedelic_furs;944 +boyzone;945 +the_chemical_brothers;946 +johnny_tillotson;947 +joe_cocker;948 +babyface;949 +wet_wet_wet;950 +tom_petty;951 +lesley_gore;952 +deorro;953 +war;954 +wolfgang_schneiderhan;955 +isaac_hayes;956 +beyonc;957 +gordon_jenkins;958 +flo_rida;959 +captain_tennille;960 +adolf_busch;961 +bobby_bare;962 +johnnie_taylor;963 +above_beyond;964 +robin_thicke;965 +ja_rule;966 +barry_white;967 +florence_the_machine;968 +the_jimi_hendrix_experience;969 +gabrielle;970 +leon_fleisher;971 +yehudi_menuhin;972 +george_harrison;973 +kate_bush;974 +u2;975 +nancy_sinatra;976 +the_everly_brothers;977 +peter_green;978 +cat_stevens;979 +the_new_seekers;980 +itzhak_perlman;981 +red_nichols_his_five_pennies;982 +the_script;983 +ijahman_levi;984 +rihanna;985 +joan_jett_and_the_blackhearts;986 +the_dorsey_brothers_orchestra;987 +charlie_barnet;988 +lmfao;989 +112;990 +kelis;991 +john_mccormack;992 +guns_n_roses;993 +gordon_macrae;994 +buddy_holly;995 +franz_schubert;996 +tommy_roe;997 +garbage;998 +bow_wow;999 +belle_and_sebastian;1000 +paul_tortelier;1001 +johnny_nash;1002 +lazar_berman;1003 +avicii;1004 +5_seconds_of_summer;1005 +mississippi_fred_mcdowell;1006 +ivan_moravec;1007 +little_richard;1008 +john_ogdon;1009 +dr_dre;1010 +andy_russell;1011 +sex_pistols;1012 +puddle_of_mudd;1013 +june_carter_cash;1014 +freddie_king;1015 +dino_ciani;1016 +h_sker_d;1017 +nicky_romero;1018 +shania_twain;1019 +major_lazer;1020 +usher;1021 +madonna;1022 +nsync;1023 +the_o_jays;1024 +faith_hill;1025 +terence_trent_d_arby;1026 +gene_chandler;1027 +lisa_stansfield;1028 +pharrell_williams;1029 +david_geringas;1030 +dr_alimantado;1031 +jack_scott;1032 +vladimir_horowitz;1033 +genesis;1034 +jessica_simpson;1035 +peter_gabriel;1036 +spike_jones_and_his_city_slickers;1037 +leonard_rose;1038 +richard_strauss;1039 +mgmt;1040 +blink_182;1041 +ella_fitzgerald;1042 +carrie_underwood;1043 +evgeny_kissin;1044 +olly_murs;1045 +ky_mani_marley;1046 +rose_royce;1047 +desmond_dekker;1048 +montell_jordan;1049 +little_river_band;1050 +t_pain;1051 +gary_allan;1052 +chubby_checker;1053 +the_diamonds;1054 +creed;1055 +louis_jordan;1056 +vernon_dalhart;1057 +gilbert_o_sullivan;1058 +ziggy_marley;1059 +irene_cara;1060 +katy_perry;1061 +all_saints;1062 +benjamin_britten;1063 +p_m_dawn;1064 +iona_brown;1065 +the_lettermen;1066 +natalie_imbruglia;1067 +viktoria_mullova;1068 +zac_brown_band;1069 +bj_rk;1070 +mutabaruka;1071 +jermaine_jackson;1072 +the_impressions;1073 +spandau_ballet;1074 +luther_vandross;1075 +thompson_twins;1076 +travis_scott;1077 +roots_radics;1078 +madness;1079 +skrillex;1080 +the_smiths;1081 +van_halen;1082 +the_four_seasons;1083 +j_b_lenoir;1084 +johnny_rivers;1085 +bob_marley_the_wailers;1086 +albert_collins;1087 +arctic_monkeys;1088 +billy_joel;1089 +joe_nichols;1090 +chicago;1091 +coldplay;1092 +blue;1093 +papa_roach;1094 +r_e_m_;1095 +eddie_money;1096 +ellie_goulding;1097 +gym_class_heroes;1098 +the_charlie_daniels_band;1099 +bette_midler;1100 +hubert_sumlin;1101 +phil_harris;1102 +arturo_benedetti_michelangeli;1103 +steps;1104 +simon_and_garfunkel;1105 +gyptian;1106 +britney_spears;1107 +lang_lang;1108 +blackstreet;1109 +the_dave_clark_five;1110 +the_chi_lites;1111 +wolfgang_amadeus_mozart;1112 +johnnie_ray;1113 +elvis_presley;1114 +red_norvo;1115 +the_velvet_underground;1116 +nelly_furtado;1117 +connee_boswell;1118 +soundgarden;1119 +dr_hook_the_medicine_show;1120 +led_zeppelin;1121 +boney_m_;1122 +gregor_piatigorsky;1123 +john_anderson;1124 +joni_james;1125 +the_all_american_rejects;1126 +marcia_griffiths;1127 +ben_bernie;1128 +eric_prydz;1129 +the_three_suns;1130 +albert_king;1131 +jodeci;1132 +inner_circle;1133 +don_cornell;1134 +jeff_healey;1135 +brian_mcknight;1136 +the_stranglers;1137 +adam_faith;1138 +francis_poulenc;1139 +fall_out_boy;1140 +the_jets;1141 +groundation;1142 +randy_newman;1143 +jane_s_addiction;1144 +bobby_vinton;1145 +guiomar_novaes;1146 +bo_diddley;1147 +philadelphia_orchestra;1148 +garrick_ohlsson;1149 +evanescence;1150 +wilhelm_backhaus;1151 +the_platters;1152 +the_seekers;1153 +selena_gomez;1154 +eddy_grant;1155 +jan_garber;1156 +gioacchino_rossini;1157 +christina_aguilera;1158 +stevie_nicks;1159 +color_me_badd;1160 +sandie_shaw;1161 +migos;1162 +the_allman_brothers_band;1163 +will_young;1164 +new_edition;1165 +radiohead;1166 +orbital;1167 +the_judds;1168 +dan_fogelberg;1169 +pascal_rog_;1170 +leona_lewis;1171 +charlie_patton;1172 +yann_tiersen;1173 +the_abyssinians;1174 +frank_ifield;1175 +john_mayer;1176 +roger_wolfe_kahn;1177 +the_mcguire_sisters;1178 +junior_reid;1179 +bukka_white;1180 +macy_gray;1181 +billy_currington;1182 +the_tremeloes;1183 +ac_dc;1184 +little_walter;1185 +gorillaz;1186 +the_hilltoppers;1187 +gil_shaham;1188 +little_mix;1189 +supertramp;1190 +third_world;1191 +david_garrett;1192 +the_lovin_spoonful;1193 +chris_lake;1194 +louis_lortie;1195 +shakira;1196 +vanessa_williams;1197 +the_bangles;1198 +mark_chesnutt;1199 +keith_whitley;1200 +roxy_music;1201 +betty_hutton;1202 +cheryl_cole;1203 +the_notorious_b_i_g_;1204 +kesha;1205 +boston;1206 +gerald_moore;1207 +heinrich_schiff;1208 +joy_division;1209 +kenny_loggins;1210 +nilsson;1211 +counting_crows;1212 +simply_red;1213 +aaron_tippin;1214 +sweet;1215 +sugababes;1216 +florida_georgia_line;1217 +lonnie_mack;1218 +jacob_miller;1219 +the_police;1220 +the_chordettes;1221 +fats_domino;1222 +willy_deville;1223 +bob_crosby;1224 +roy_clark;1225 +dinu_lipatti;1226 +alison_krauss;1227 +frankie_avalon;1228 +ella_mae_morse;1229 +linton_kwesi_johnson;1230 +glenn_frey;1231 +rudy_vall_e_his_connecticut_yankees;1232 +dj_snake;1233 +toots_the_maytals;1234 +annie_lennox;1235 +paramore;1236 +john_browning;1237 +sister_sledge;1238 +julian_lloyd_webber;1239 +kanye_west;1240 +christopher_cross;1241 +professor_longhair;1242 +flume;1243 +sophie_tucker;1244 +third_eye_blind;1245 +beyonc_;1246 +weezer;1247 +kelly_clarkson;1248 +take_that;1249 +ludwig_van_beethoven;1250 +the_cars;1251 +george_michael;1252 +chaka_khan;1253 +arty;1254 +steel_pulse;1255 +bunny_wailer;1256 +the_troggs;1257 +nick_lucas;1258 +keb_mo_;1259 +rise_against;1260 +mickey_gilley;1261 +poison;1262 +debbie_gibson;1263 +kim_wilde;1264 +sammy_davis_jr;1265 +jonas_brothers;1266 +cage_the_elephant;1267 +son_house;1268 +birth_control;1269 +faithless;1270 +cher;1271 +seether;1272 +new_kids_on_the_block;1273 +rage;1274 +richie_spice;1275 +sam_smith;1276 +the_marvelettes;1277 +the_jackson_5;1278 +bobbie_gentry;1279 +macklemore_ryan_lewis;1280 +s_club_7;1281 +billy_jones_ernest_hare;1282 +arcana;1283 +blasterjaxx;1284 +will_smith;1285 +ray_miller;1286 +sugar_ray;1287 +ziggy_marley_the_melody_makers;1288 +aaron_copland;1289 +diddy;1290 +daughtry;1291 +beach_house;1292 +the_dillinger_escape_plan;1293 +lonestar;1294 +foreigner;1295 +lionel_richie;1296 +roberta_flack;1297 +the_carter_family;1298 +demi_lovato;1299 +joseph_haydn;1300 +sander_van_doorn;1301 +underworld;1302 +deborah_cox;1303 +the_grass_roots;1304 +bananarama;1305 +iggy_azalea;1306 +3_doors_down;1307 +the_partridge_family;1308 +lead_belly;1309 +johnny_long;1310 +jagged_edge;1311 +the_derek_trucks_band;1312 +eddie_fisher;1313 +pablo_casals;1314 +the_original_dixieland_jazz_band;1315 +miley_cyrus;1316 +john_powell;1317 +the_black_eyed_peas;1318 +edvard_grieg;1319 +maurizio_pollini;1320 +nathan_milstein;1321 +twenty_one_pilots;1322 +rudolf_firku_n_;1323 +nine_inch_nails;1324 +the_four_aces;1325 +jimmy_rogers;1326 +salt_n_pepa;1327 +yellow_claw;1328 +the_strokes;1329 +bobby_brown;1330 +juelz_santana;1331 +staind;1332 +bj_rn_ulvaeus_benny_andersson;1333 +the_j_geils_band;1334 +the_muppets;1335 +gwen_stefani;1336 +fedde_le_grand;1337 +imagine_dragons;1338 +leo_sayer;1339 +the_animals;1340 +the_b_52_s;1341 +furry_lewis;1342 +ciara;1343 +larry_clinton;1344 +dire_straits;1345 +pato_banton_the_reggae_revol;1346 +goodie_mob;1347 +disclosure;1348 +georges_bizet;1349 +sonny_terry_brownie_mcghee;1350 +jim_croce;1351 +nelson;1352 +jason_derulo;1353 +guy_mitchell;1354 +the_fontane_sisters;1355 +sonny_boy_williamson_i;1356 +mirah;1357 +jimmy_rushing;1358 +john_michael_montgomery;1359 +michael_nesmith;1360 +george_clinton;1361 +burt_bacharach;1362 +v6;1363 +slim_thug;1364 +belinda_carlisle;1365 +philip_glass;1366 +slade;1367 +pete_townshend;1368 +oingo_boingo;1369 +andrew_lloyd_webber;1370 +the_collectors;1371 +boy_george;1372 +utada_hikaru;1373 +mel_torm;1374 +diana_krall;1375 +melanie_c;1376 +john_hammond;1377 +peter_green_splinter_group;1378 +trouble;1379 +g_unit;1380 +ferlin_husky;1381 +arcade_fire;1382 +latino;1383 +krayzie_bone;1384 +man;1385 +dave_clark_five;1386 +the_stone_roses;1387 +young_jeezy;1388 +blood_sweat_tears;1389 +kumikameli;1390 +dmx;1391 +ice_cube;1392 +eagles;1393 +jill_scott;1394 +xtc;1395 +peggy_march;1396 +michael_bubl;1397 +raimon;1398 +two_mix;1399 +dulce_pontes;1400 +the_unseen;1401 +hank_locklin;1402 +the_notorious_b_i_g;1403 +bumblefoot;1404 +the_busters;1405 +rick_ross;1406 +tegan_and_sara;1407 +skeeter_davis;1408 +curtis_mayfield;1409 +sade;1410 +wings;1411 +lorrie_morgan;1412 +saga;1413 +a_r_rahman;1414 +martha_wainwright;1415 +nas;1416 +will_i_am;1417 +kirsty_maccoll;1418 +angel;1419 +dave_davies;1420 +iggy_pop;1421 +jojo;1422 +sammy_hagar;1423 +ray_davies;1424 +and_one;1425 +neil_young;1426 +mikael_wiehe;1427 +the_cardigans;1428 +cage;1429 +dottie_west;1430 +keri_hilson;1431 +johnny_hallyday;1432 +bill_nelson;1433 +fifteen;1434 +deen;1435 +bobby_v;1436 +lil_yachty;1437 +too_hort;1438 +bernard_lavilliers;1439 +hank_thompson;1440 +the_chieftains;1441 +daryl_hall;1442 +antonio_carlos_jobim;1443 +aventura;1444 +the_the;1445 +van_morrison;1446 +wynonna_judd;1447 +gomez;1448 +charles_aznavour;1449 +m83;1450 +gnr;1451 +all;1452 +emmylou_harris;1453 +lee_hazlewood;1454 +mew;1455 +uriah_heep;1456 +yoko_ono;1457 +abw_rts;1458 +john_legend;1459 +d12;1460 +kitty_wells;1461 +timbiriche;1462 +shel_silverstein;1463 +cam_ron;1464 +rosanne_cash;1465 +2_chainz;1466 +tricky;1467 +8ball_mjg;1468 +flatt_scruggs;1469 +bill_anderson;1470 +emil_ana_torrini;1471 +ufo;1472 +mos_def;1473 +danzig;1474 +juan_gabriel;1475 +common;1476 +raekwon;1477 +france_gall;1478 +nicole_scherzinger;1479 +r_yksopp;1480 +sammie;1481 +lena_horne;1482 +david_byrne;1483 +paul_williams;1484 +josh_groban;1485 +the_gathering;1486 +frank_boeijen;1487 +scooter;1488 +steve_wariner;1489 +mika;1490 +pete_seeger;1491 +tex_ritter;1492 +warrant;1493 +porter_wagoner;1494 +field_music;1495 +three_6_mafia;1496 +jim_jones;1497 +daniel_o_donnell;1498 +brentalfloss;1499 +wyclef_jean;1500 +hey;1501 +bizzy_bone;1502 +the_mccalmans;1503 +blues_traveler;1504 +massive_attack;1505 +woody_guthrie;1506 +art_garfunkel;1507 +andrea_bocelli;1508 +david_crosby;1509 +dream;1510 +soul_asylum;1511 +natalie_merchant;1512 +shawn_colvin;1513 +jonny_lang;1514 +funeral_for_a_friend;1515 +boz_scaggs;1516 +example;1517 +lionel_hampton;1518 +the_tubes;1519 +marc_anthony;1520 +good_riddance;1521 +moonlight;1522 +marc_almond;1523 +rza;1524 +die_rzte;1525 +rbd;1526 +alejandro_fern_ndez;1527 +wanda_jackson;1528 +lara_fabian;1529 +julio_iglesias;1530 +jeff_beck;1531 +peabo_bryson;1532 +no_fun_at_all;1533 +prong;1534 +canibus;1535 +krs_one;1536 +u_s_bombs;1537 +trust;1538 +stonewall_jackson;1539 +jos_feliciano;1540 +m_a;1541 +polysics;1542 +n_e_r_d;1543 +sesame_street;1544 +lio;1545 +myl_ne_farmer;1546 +iris_dement;1547 +lily_allen;1548 +spoken;1549 +architects;1550 +jack_johnson;1551 +molly_hatchet;1552 +cypress_hill;1553 +future;1554 +the_nits;1555 +per_gessle;1556 +live;1557 +beau;1558 +deana_carter;1559 +lil_flip;1560 +fran_oise_hardy;1561 +billy_ray_cyrus;1562 +pepper;1563 +run_d_m_c;1564 +levon_helm;1565 +insane_clown_posse;1566 +stars;1567 +jean_michel_jarre;1568 +thunder;1569 +juanes;1570 +simple_plan;1571 +method_man;1572 +smash_mouth;1573 +meek_mill;1574 +fat_joe;1575 +kenny_wayne_shepherd;1576 +jhen_aiko;1577 +the_manhattan_transfer;1578 +joss_stone;1579 +cee_lo_green;1580 +tyrese;1581 +charlotte_martin;1582 +rodney_crowell;1583 +acappella;1584 +die_prinzen;1585 +pentatonix;1586 +abney_park;1587 +smooth_mcgroove;1588 +the_magnetic_fields;1589 +the_nylons;1590 +wise_guys;1591 +coil;1592 +do_as_infinity;1593 +lords_of_acid;1594 +the_church;1595 +chris_rea;1596 +jota_quest;1597 +miguel_bos;1598 +gang_starr;1599 +masta_ace;1600 +brand_new;1601 +mac_miller;1602 +cathedral;1603 +corrosion_of_conformity;1604 +country_joe_mcdonald;1605 +eric_johnson;1606 +grateful_dead;1607 +janis_joplin;1608 +john_miles;1609 +king_gizzard_the_lizard_wizard;1610 +ted_nugent;1611 +combichrist;1612 +alkaline_trio;1613 +anathema;1614 +angus_julia_stone;1615 +anna_ternheim;1616 +anthony_phillips;1617 +steve_hackett;1618 +aviators;1619 +banda_calypso;1620 +blue_stahli;1621 +the_boys;1622 +capital_inicial;1623 +city_and_colour;1624 +colin_hay;1625 +collective_soul;1626 +dashboard_confessional;1627 +david_rovics;1628 +david_usher;1629 +die_toten_hosen;1630 +funny_van_dannen;1631 +dirty_heads;1632 +tech_n9ne;1633 +elisa;1634 +emmerson_nogueira;1635 +engenheiros_do_hawaii;1636 +eric_bibb;1637 +maria_muldaur;1638 +panic_at_the_disco;1639 +punchline;1640 +godsmack;1641 +self;1642 +heideroosjes;1643 +sinner;1644 +heather_nova;1645 +hoobastank;1646 +quietdrive;1647 +hyde;1648 +jaguares;1649 +bert_jansch;1650 +jonatha_brooke;1651 +joni_mitchell;1652 +the_band;1653 +josh_garrels;1654 +josh_woodward;1655 +william_fitzsimmons;1656 +katie_melua;1657 +jamie_cullum;1658 +kristin_hersh;1659 +kt_tunstall;1660 +legi_o_urbana;1661 +the_zombies;1662 +francesco_de_gregori;1663 +m_ward;1664 +beth_orton;1665 +magnum;1666 +motorpsycho;1667 +marillion;1668 +jars_of_clay;1669 +mason_jennings;1670 +matt_nathanson;1671 +matthew_good;1672 +edguy;1673 +gamma_ray;1674 +minus_the_bear;1675 +mohsen_namjoo;1676 +nerina_pallot;1677 +never_shout_never;1678 +regina_spektor;1679 +passenger;1680 +paul_kelly;1681 +the_style_council;1682 +peter_hammill;1683 +phantom_planet;1684 +phil_keaggy;1685 +richard_thompson;1686 +said_the_whale;1687 +samsas_traum;1688 +senses_fail;1689 +sevendust;1690 +seventh_day_slumber;1691 +joan_baez;1692 +sister_hazel;1693 +slightly_stoopid;1694 +sophie_zelmani;1695 +suzanne_vega;1696 +tatiana;1697 +teoman;1698 +the_choir;1699 +charlotte_church;1700 +darlene_zschech;1701 +the_front_bottoms;1702 +the_maine;1703 +the_white_buffalo;1704 +little_big_town;1705 +threshold;1706 +tourniquet;1707 +everything_but_the_girl;1708 +vertical_horizon;1709 +vonda_shepard;1710 +warren_zevon;1711 +sarah_brightman;1712 +blackfoot;1713 +black_label_society;1714 +z_lia_duncan;1715 +2;1716 +alejandro_lerner;1717 +beth_nielsen_chapman;1718 +mercury_rev;1719 +brian_wilson;1720 +barenaked_ladies;1721 +carbon_leaf;1722 +celtic_woman;1723 +hayley_westenra;1724 +crowded_house;1725 +delta_goodrem;1726 +elbow;1727 +resurrection_band;1728 +nancy_wilson;1729 +janis_ian;1730 +jann_arden;1731 +jill_sobule;1732 +jos_augusto;1733 +xuxa;1734 +k_d_lang;1735 +kim_carnes;1736 +los_lobos;1737 +mandy_moore;1738 +marc_cohn;1739 +maureen_mcgovern;1740 +melissa_manchester;1741 +patti_labelle;1742 +helene_fischer;1743 +laura_pausini;1744 +ivan_lins;1745 +thal_a;1746 +mike_the_mechanics;1747 +paul_carrack;1748 +natasha_st_pier;1749 +michael_mcdonald;1750 +olivia;1751 +dizzee_rascal;1752 +sam_phillips;1753 +serge_gainsbourg;1754 +jane_birkin;1755 +luis_miguel;1756 +sondre_lerche;1757 +stan_ridgway;1758 +susan_boyle;1759 +mike_oldfield;1760 +ces_ria_vora;1761 +agonoize;1762 +funker_vogt;1763 +god_module;1764 +hocico;1765 +nachtmahr;1766 +suicide_commando;1767 +alejandro_escovedo;1768 +southside_johnny_the_asbury_jukes;1769 +broken_social_scene;1770 +vigilantes_of_love;1771 +billy_bragg;1772 +wilco;1773 +frank_black_and_the_catholics;1774 +blue_rodeo;1775 +brandi_carlile;1776 +patty_griffin;1777 +calexico;1778 +cass_mccombs;1779 +chris_knight;1780 +conor_oberst;1781 +corb_lund;1782 +cowboy_junkies;1783 +cracker;1784 +cross_canadian_ragweed;1785 +dave_alvin;1786 +drive_by_truckers;1787 +eleni_mandell;1788 +lucinda_williams;1789 +fred_eaglesmith;1790 +dar_williams;1791 +the_jayhawks;1792 +lana_del_rey;1793 +tim_o_brien;1794 +hank_williams_iii;1795 +james_mcmurtry;1796 +joe_henry;1797 +john_stewart;1798 +josh_ritter;1799 +lambchop;1800 +nanci_griffith;1801 +norma_jean;1802 +lyle_lovett;1803 +matthew_ryan;1804 +my_morning_jacket;1805 +neko_case;1806 +the_new_pornographers;1807 +blue_october;1808 +okkervil_river;1809 +old_97_s;1810 +ray_wylie_hubbard;1811 +richmond_fontaine;1812 +robert_earl_keen;1813 +rocky_votolato;1814 +ryan_adams;1815 +whiskeytown;1816 +son_volt;1817 +steve_earle;1818 +the_avett_brothers;1819 +the_bottle_rockets;1820 +the_felice_brothers;1821 +arlo_guthrie;1822 +the_handsome_family;1823 +the_mavericks;1824 +ten_years_after;1825 +the_walkabouts;1826 +todd_snider;1827 +vic_chesnutt;1828 +iron_wine;1829 +wovenhand;1830 +x;1831 +big_audio_dynamite;1832 +globe;1833 +carter_the_unstoppable_sex_machine;1834 +allison_moorer;1835 +front_line_assembly;1836 +the_national;1837 +the_fall;1838 +public_image_ltd;1839 +public_enemy;1840 +wire;1841 +a_tribe_called_quest;1842 +de_la_soul;1843 +aesop_rock;1844 +buck_65;1845 +caparezza;1846 +childish_gambino;1847 +the_roots;1848 +colbie_caillat;1849 +big_sean;1850 +dj_gruff;1851 +tyler_the_creator;1852 +dokken;1853 +fun_lovin_criminals;1854 +talib_kweli;1855 +jane_air;1856 +k_i_z;1857 +kid_cudi;1858 +jedi_mind_tricks;1859 +celph_titled;1860 +lupe_fiasco;1861 +bun_b;1862 +scarface;1863 +ghostface_killah;1864 +robyn;1865 +rehab;1866 +swollen_members;1867 +styles_p;1868 +the_streets;1869 +wale;1870 +joe_budden;1871 +tank;1872 +10_years;1873 +36_crazyfists;1874 +apocalyptica;1875 +nina_hagen;1876 +anastacia;1877 +black_stone_cherry;1878 +blindside;1879 +breaking_benjamin;1880 +bring_me_the_horizon;1881 +bullet_for_my_valentine;1882 +cave_in;1883 +chevelle;1884 +d_espairsray;1885 +death_angel;1886 +deftones;1887 +demon_hunter;1888 +demon;1889 +devin_townsend_project;1890 +devin_townsend;1891 +doa;1892 +dir_en_grey;1893 +disturbed;1894 +dope;1895 +drowning_pool;1896 +eighteen_visions;1897 +entombed;1898 +faith_no_more;1899 +fear_factory;1900 +fightstar;1901 +five_finger_death_punch;1902 +finger_eleven;1903 +flyleaf;1904 +grinspoon;1905 +guano_apes;1906 +h_blockx;1907 +halestorm;1908 +hamlet;1909 +helmet;1910 +bt;1911 +ill_ni_o;1912 +in_flames;1913 +in_this_moment;1914 +him;1915 +j_b_o;1916 +katatonia;1917 +killswitch_engage;1918 +xzibit;1919 +lacuna_coil;1920 +phish;1921 +limp_bizkit;1922 +living_colour;1923 +viikate;1924 +marilyn_manson;1925 +megaherz;1926 +falco;1927 +melvins;1928 +monster_magnet;1929 +mushroomhead;1930 +nonpoint;1931 +soil;1932 +otep;1933 +p_o_d;1934 +powerman_5000;1935 +primus;1936 +project_86;1937 +red;1938 +kris_allen;1939 +rob_zombie;1940 +ozzy_osbourne;1941 +rollins_band;1942 +saliva;1943 +sepultura;1944 +shihad;1945 +skillet;1946 +skindred;1947 +slipknot;1948 +smile_empty_soul;1949 +danielson;1950 +soilwork;1951 +sonic_syndicate;1952 +static_x;1953 +stone_sour;1954 +taproot;1955 +the_notwist;1956 +the_word_alive;1957 +theory_of_a_deadman;1958 +therapy;1959 +los_tucanes_de_tijuana;1960 +manu_chao;1961 +volbeat;1962 +zebrahead;1963 +hed_p_e;1964 +and_you_will_know_us_by_the_trail_of_dead;1965 +10_000_maniacs;1966 +311;1967 +77s;1968 +yes;1969 +david_lee_roth;1970 +hillsong;1971 +afi;1972 +adam_sandler;1973 +afterhours;1974 +hawkwind;1975 +all_about_eve;1976 +all_time_low;1977 +allison_crowe;1978 +amanda_palmer;1979 +american_music_club;1980 +amplifier;1981 +robert_wyatt;1982 +anberlin;1983 +andrew_bird;1984 +ani_difranco;1985 +apoptygma_berzerk;1986 +apulanta;1987 +arab_strap;1988 +joseph_arthur;1989 +tom_rosenthal;1990 +ash;1991 +asian_kung_fu_generation;1992 +poets_of_the_fall;1993 +babas_nicos;1994 +bayside;1995 +beatsteaks;1996 +ben_folds;1997 +ben_folds_five;1998 +ben_harper;1999 +better_than_ezra;2000 +bettie_serveert;2001 +big_country;2002 +big_head_todd_and_the_monsters;2003 +big_sugar;2004 +billy_talent;2005 +today_is_the_day;2006 +red_flag;2007 +black_rebel_motorcycle_club;2008 +megadeth;2009 +blonde_redhead;2010 +bob_mould;2011 +bodeans;2012 +bowling_for_soup;2013 +buck_tick;2014 +butch_walker;2015 +butthole_surfers;2016 +caf_tacvba;2017 +cake;2018 +camper_van_beethoven;2019 +carmen_consoli;2020 +mario_venuti;2021 +franco_battiato;2022 +catherine_wheel;2023 +catupecu_machu;2024 +cem_adrian;2025 +john_cale;2026 +charlie_brown_jr;2027 +nena;2028 +chumbawamba;2029 +clutch;2030 +cl;2031 +cmx;2032 +coheed_and_cambria;2033 +cold_war_kids;2034 +travis;2035 +coma;2036 +concrete_blonde;2037 +mint_condition;2038 +copeland;2039 +crash_test_dummies;2040 +joe_jackson;2041 +cristian_castro;2042 +curve;2043 +dada;2044 +daniel_amos;2045 +daniel_johnston;2046 +dave_matthews_band;2047 +burning_heads;2048 +david_gray;2049 +david_sylvian;2050 +deacon_blue;2051 +deerhoof;2052 +del_amitri;2053 +dinosaur_jr;2054 +dirty_projectors;2055 +draco_rosa;2056 +duncan_sheik;2057 +jeremy_camp;2058 +edwyn_collins;2059 +eels;2060 +nightwish;2061 +element_of_crime;2062 +embrace;2063 +enter_shikari;2064 +ulver;2065 +everclear;2066 +everlast;2067 +eyeshine;2068 +dio;2069 +faust_o;2070 +feeder;2071 +atmosphere;2072 +filter;2073 +firewater;2074 +fishbone;2075 +fountains_of_wayne;2076 +four_year_strong;2077 +steve_green;2078 +fresno;2079 +gang_of_four;2080 +good_charlotte;2081 +blood_on_the_dance_floor;2082 +graham_coxon;2083 +melissa_etheridge;2084 +tony_joe_white;2085 +guided_by_voices;2086 +robert_pollard;2087 +guster;2088 +elliott_smith;2089 +hedley;2090 +hole;2091 +hollywood_undead;2092 +hot_chip;2093 +l_arc_en_ciel;2094 +ian_brown;2095 +idlewild;2096 +jimmy_eat_world;2097 +fish;2098 +ingrid_michaelson;2099 +inme;2100 +inspiral_carpets;2101 +raf;2102 +james;2103 +jean_leloup;2104 +weird_al_yankovic;2105 +jeff_buckley;2106 +john_frusciante;2107 +dr_john;2108 +pj_harvey;2109 +jonathan_coulton;2110 +juliana_hatfield;2111 +julieta_venegas;2112 +k_s_choice;2113 +kaizers_orchestra;2114 +kargo;2115 +kasabian;2116 +keane;2117 +kevin_coyne;2118 +kevin_devine;2119 +kevin_max;2120 +rich_mullins;2121 +trooper;2122 +suzy_bogguss;2123 +kill_hannah;2124 +kisp_l_s_a_borz;2125 +kult;2126 +my_life_with_the_thrill_kill_kult;2127 +kutless;2128 +la_barranca;2129 +la_ley;2130 +lao_che;2131 +lech_janerka;2132 +les_cowboys_fringants;2133 +les_fatals_picards;2134 +les_rita_mitsouko;2135 +sparks;2136 +lifehouse;2137 +lisa_germano;2138 +ed_harcourt;2139 +lisa_loeb;2140 +liz_phair;2141 +local_h;2142 +lost_dogs;2143 +lostprophets;2144 +love_and_rockets;2145 +lucybell;2146 +lulu_santos;2147 +gabriel_o_pensador;2148 +adam_lambert;2149 +madrugada;2150 +mancha_de_rolando;2151 +manchester_orchestra;2152 +mando_diao;2153 +foetus;2154 +mark_lanegan;2155 +matthew_sweet;2156 +max_mo_park;2157 +mayday_parade;2158 +meat_puppets;2159 +men_without_hats;2160 +meshell_ndegeocello;2161 +midnight_oil;2162 +dance_gavin_dance;2163 +molotov;2164 +ov7;2165 +monkey_majik;2166 +suede;2167 +fernando_ortega;2168 +motion_city_soundtrack;2169 +mudhoney;2170 +mutemath;2171 +mercyme;2172 +m_o_morta;2173 +natalia_lafourcade;2174 +natewantstobattle;2175 +needtobreathe;2176 +split_enz;2177 +sum_41;2178 +no_te_va_gustar;2179 +noir_d_sir;2180 +t_tes_raides;2181 +o_rappa;2182 +o_a_r;2183 +ocean_colour_scene;2184 +omul_cu_obolani;2185 +one_ok_rock;2186 +2raumwohnung;2187 +our_lady_peace;2188 +pain;2189 +panda;2190 +parokya_ni_edgar;2191 +pato_fu;2192 +paul_westerberg;2193 +pere_ubu;2194 +pete_yorn;2195 +peter_murphy;2196 +placebo;2197 +plain_white_t_s;2198 +pop_will_eat_itself;2199 +porcupine_tree;2200 +powderfinger;2201 +cat_power;2202 +casting_crowns;2203 +primal_scream;2204 +m_tley_cr_e;2205 +the_used;2206 +raimundos;2207 +mark_knopfler;2208 +mark_kozelek;2209 +danko_jones;2210 +relient_k;2211 +raffi;2212 +renaud;2213 +richard_hawley;2214 +rickie_lee_jones;2215 +the_shins;2216 +rilo_kiley;2217 +robyn_hitchcock;2218 +mose_allison;2219 +roy_harper;2220 +rucka_rucka_ali;2221 +rx_bandits;2222 +saez;2223 +samiam;2224 +sarah_slean;2225 +say_anything;2226 +scout_niblett;2227 +screaming_females;2228 +shannon_wright;2229 +silverchair;2230 +sin_ad_o_connor;2231 +siouxsie_and_the_banshees;2232 +sixpence_none_the_richer;2233 +skank;2234 +skunk_anansie;2235 +sleater_kinney;2236 +sloan;2237 +social_distortion;2238 +sophie_hunger;2239 +e_40;2240 +steve_wynn;2241 +subsonica;2242 +joe_walsh;2243 +super_furry_animals;2244 +superchunk;2245 +supergrass;2246 +swervedriver;2247 +switchfoot;2248 +dido;2249 +takida;2250 +taking_back_sunday;2251 +teenage_fanclub;2252 +w_a_s_p;2253 +the_afghan_whigs;2254 +the_apples_in_stereo;2255 +the_ataris;2256 +smoking_popes;2257 +the_bluetones;2258 +the_breeders;2259 +the_cat_empire;2260 +the_charlatans_uk;2261 +the_clarks;2262 +guy_clark;2263 +the_comsat_angels;2264 +the_connells;2265 +the_coral;2266 +the_cribs;2267 +the_cult;2268 +bobby_o;2269 +the_mission;2270 +blue_yster_cult;2271 +the_dandy_warhols;2272 +the_dear_hunter;2273 +the_decemberists;2274 +the_early_november;2275 +thievery_corporation;2276 +the_fratellis;2277 +the_gaslight_anthem;2278 +jim_brickman;2279 +falling_up;2280 +the_hives;2281 +the_innocence_mission;2282 +the_jazz_butcher;2283 +the_jesus_lizard;2284 +the_lemonheads;2285 +babyshambles;2286 +the_living_end;2287 +the_matrixx;2288 +the_mother_hips;2289 +the_mountain_goats;2290 +the_muffs;2291 +the_pillows;2292 +the_posies;2293 +the_presidents_of_the_united_states_of_america;2294 +the_rasmus;2295 +the_raveonettes;2296 +the_saints;2297 +the_samples;2298 +bad_religion;2299 +the_smithereens;2300 +the_soundtrack_of_our_lives;2301 +the_tea_party;2302 +mayday;2303 +the_triffids;2304 +the_vines;2305 +the_violet_burning;2306 +the_wallflowers;2307 +testament;2308 +the_divine_comedy;2309 +third_day;2310 +thrice;2311 +tindersticks;2312 +tism;2313 +tit_s;2314 +toad_the_wet_sprocket;2315 +tocotronic;2316 +tom_mcrae;2317 +tori_amos;2318 +tracy_chapman;2319 +trashcan_sinatras;2320 +tre_allegri_ragazzi_morti;2321 +tub_ring;2322 +unkle;2323 +unwritten_law;2324 +uverworld;2325 +vast;2326 +verdena;2327 +veruca_salt;2328 +face_to_face;2329 +virus;2330 +voltaire;2331 +we_the_kings;2332 +the_kooks;2333 +lindisfarne;2334 +seals_crofts;2335 +andy_partridge;2336 +xutos_pontap_s;2337 +yellowcard;2338 +yup;2339 +leevi_and_the_leavings;2340 +zo;2341 +zucchero;2342 +z;2343 +ebnem_ferah;2344 +air;2345 +alice;2346 +boards_of_canada;2347 +brian_eno;2348 +burzum;2349 +daniel_lanois;2350 +enigma;2351 +juana_molina;2352 +lisa_gerrard;2353 +nox_arcana;2354 +renard;2355 +schiller;2356 +sigur_r_s;2357 +steven_wilson;2358 +swans;2359 +wolfgun;2360 +xiu_xiu;2361 +michael_johnson;2362 +montgomery_gentry;2363 +the_stanley_brothers;2364 +john_waite;2365 +shelby_lynne;2366 +judy_collins;2367 +burl_ives;2368 +the_irish_rovers;2369 +david_wilcox;2370 +devendra_banhart;2371 +doc_watson;2372 +bill_monroe;2373 +michael_martin_murphey;2374 +gordon_bok;2375 +asleep_at_the_wheel;2376 +the_browns;2377 +nana_mouskouri;2378 +jerry_jeff_walker;2379 +steve_goodman;2380 +malcolm_holcombe;2381 +malvina_reynolds;2382 +odetta;2383 +tom_paxton;2384 +strawbs;2385 +phil_ochs;2386 +harry_chapin;2387 +ramblin_jack_elliott;2388 +roger_mcguinn;2389 +gene_clark;2390 +mat_kearney;2391 +the_brothers_four;2392 +tom_russell;2393 +townes_van_zandt;2394 +uncle_dave_macon;2395 +delbert_mcclinton;2396 +john_hiatt;2397 +justin_townes_earle;2398 +mark_erelli;2399 +over_the_rhine;2400 +steve_forbert;2401 +manfred_mann_s_earth_band;2402 +mot_rhead;2403 +rudimentary_peni;2404 +illapu;2405 +inti_illimani;2406 +quilapay_n;2407 +v_ctor_jara;2408 +skylark;2409 +adam_green;2410 +cold_chisel;2411 +guy_sebastian;2412 +jefferson_starship;2413 +the_alan_parsons_project;2414 +ali_project;2415 +modern_talking;2416 +animal_collective;2417 +banco_del_mutuo_soccorso;2418 +ben_lee;2419 +bryan_ferry;2420 +buffy_sainte_marie;2421 +colin_blunstone;2422 +cursive;2423 +elysian_fields;2424 +emerson_lake_palmer;2425 +gino_vannelli;2426 +g_rard_manset;2427 +hot_dad;2428 +marina_and_the_diamonds;2429 +ismo_alanko;2430 +kansas;2431 +kari_peitsamo;2432 +laibach;2433 +laurie_anderson;2434 +puhdys;2435 +na_o_zumbi;2436 +roger_waters;2437 +rush;2438 +the_walker_brothers;2439 +hilltop_hoods;2440 +wolfgang_ambros;2441 +erste_allgemeine_verunsicherung;2442 +jacques_brel;2443 +rainhard_fendrich;2444 +tom_waits;2445 +adrian_belew;2446 +anne_clark;2447 +can;2448 +captain_beefheart_and_the_magic_band;2449 +deine_lakaien;2450 +devo;2451 +einst_rzende_neubauten;2452 +frank_zappa;2453 +goethes_erben;2454 +wishbone_ash;2455 +death_cab_for_cutie;2456 +antony_and_the_johnsons;2457 +jandek;2458 +nevermore;2459 +king_crimson;2460 +king_missile;2461 +the_residents;2462 +steeleye_span;2463 +vampire_rodents;2464 +the_walkmen;2465 +dog_fashion_disco;2466 +freak_kitchen;2467 +sigh;2468 +children_of_bodom;2469 +soft_machine;2470 +ara_ketu;2471 +asa_de_guia;2472 +banda_eva;2473 +ivete_sangalo;2474 +chiclete_com_banana;2475 +daniela_mercury;2476 +alejandro_sanz;2477 +timbalada;2478 +juan_luis_guerra;2479 +daddy_yankee;2480 +alceu_valen_a;2481 +luiz_gonzaga;2482 +matia_bazar;2483 +axelle_red;2484 +barbara;2485 +benny_neyman;2486 +gigi_d_agostino;2487 +jacques_higelin;2488 +caetano_veloso;2489 +gal_costa;2490 +jorge_ben;2491 +die_flippers;2492 +nicole;2493 +angra;2494 +reinhard_mey;2495 +wolf_biermann;2496 +florent_pagny;2497 +hannes_wader;2498 +tienne_daho;2499 +henri_salvador;2500 +f_lix_leclerc;2501 +daniel_lavoie;2502 +gerhard_sch_ne;2503 +g_lben_ergen;2504 +georg_kreisler;2505 +herbert_gr_nemeyer;2506 +herman_van_veen;2507 +hildegard_knef;2508 +marlene_dietrich;2509 +iu;2510 +jos_luis_rodr_guez;2511 +juliette_gr_co;2512 +klaus_hoffmann;2513 +konstantin_wecker;2514 +saltatio_mortis;2515 +luigi_tenco;2516 +maria_beth_nia;2517 +adriana_calcanhotto;2518 +marie_lafor_t;2519 +marius_m_ller_westernhagen;2520 +mina;2521 +no_l_coward;2522 +pippo_pollina;2523 +rita_lee;2524 +os_mutantes;2525 +rita_pavone;2526 +roger_whittaker;2527 +al_bano_romina_power;2528 +salvatore_adamo;2529 +simone;2530 +s_rgio_godinho;2531 +udo_j_rgens;2532 +udo_lindenberg;2533 +ulrich_roski;2534 +zaz;2535 +z_ramalho;2536 +fagner;2537 +dith_piaf;2538 +duelo;2539 +espinoza_paz;2540 +fidel_rueda;2541 +la_firma;2542 +la_arrolladora_banda_el_lim_n;2543 +voz_de_mando;2544 +sergio_vega;2545 +fool_s_garden;2546 +waltari;2547 +of_montreal;2548 +pierre_lapointe;2549 +rufus_wainwright;2550 +loudon_wainwright_iii;2551 +sufjan_stevens;2552 +machine_gun_kelly;2553 +francesco_guccini;2554 +le_orme;2555 +lucio_dalla;2556 +michel_fugain;2557 +al_jarreau;2558 +carmen_mcrae;2559 +javier_sol_s;2560 +harry_connick_jr;2561 +bap;2562 +cradle_of_filth;2563 +amorphis;2564 +avatar;2565 +bathory;2566 +behemoth;2567 +borknagar;2568 +countess;2569 +cruachan;2570 +darkthrone;2571 +hate;2572 +destruction;2573 +dimmu_borgir;2574 +eisregen;2575 +enslaved;2576 +finntroll;2577 +fates_warning;2578 +graveworm;2579 +impaled_nazarene;2580 +sentenced;2581 +king_diamond;2582 +kreator;2583 +lord_belial;2584 +marduk;2585 +mercyful_fate;2586 +stick_to_your_guns;2587 +moonspell;2588 +as_i_lay_dying;2589 +nunslaughter;2590 +rotting_christ;2591 +samael;2592 +sandy_denny;2593 +skyforger;2594 +sodom;2595 +cannibal_corpse;2596 +exodus;2597 +atreyu;2598 +theatres_des_vampires;2599 +wizard;2600 +transmetal;2601 +venom;2602 +belphegor;2603 +the_crown;2604 +moya_brennan;2605 +todd_rundgren;2606 +clay_walker;2607 +andrew_peterson;2608 +lynn_anderson;2609 +david_crowder_band;2610 +pam_tillis;2611 +norah_jones;2612 +rhonda_vincent;2613 +jamey_johnson;2614 +plumb;2615 +j_j_cale;2616 +new_riders_of_the_purple_sage;2617 +joe_diffie;2618 +kasey_chambers;2619 +leon_russell;2620 +jack_greene;2621 +the_string_cheese_incident;2622 +ystein_sunde;2623 +stephen_stills;2624 +cancerslug;2625 +robert_plant;2626 +alvin_lee;2627 +beth_hart;2628 +jimmy_buffett;2629 +billy_s_band;2630 +bunbury;2631 +nacho_vegas;2632 +calogero;2633 +georges_brassens;2634 +canned_heat;2635 +charlie_louvin;2636 +colin_james;2637 +cuby_blizzards;2638 +dick_annegarn;2639 +edoardo_bennato;2640 +eva_cassidy;2641 +gil_scott_heron;2642 +glenn_hughes;2643 +deep_purple;2644 +connie_smith;2645 +iva_zanicchi;2646 +izzy_stradlin;2647 +j_karjalainen;2648 +jack_bruce;2649 +leonard_cohen;2650 +joan_armatrading;2651 +joan_osborne;2652 +john_martyn;2653 +rio_reiser;2654 +larry_carlton;2655 +madeleine_peyroux;2656 +bruce_cockburn;2657 +kate_anna_mcgarrigle;2658 +mavis_staples;2659 +noa;2660 +ralph_mctell;2661 +renato_carosone;2662 +richie_kotzen;2663 +robben_ford;2664 +roberto_carlos;2665 +erasmo_carlos;2666 +robin_trower;2667 +rory_block;2668 +roy_buchanan;2669 +sandra_mihanovich;2670 +savoy_brown;2671 +shirley_horn;2672 +siniestro_total;2673 +slank;2674 +the_fabulous_thunderbirds;2675 +the_seatbelts;2676 +the_tragically_hip;2677 +mike_jones;2678 +trophy_scars;2679 +caravan;2680 +velhas_virgens;2681 +walter_trout;2682 +gov_t_mule;2683 +bar_o_vermelho;2684 +blue_cheer;2685 +ian_hunter;2686 +david_leb_n;2687 +de_palmas;2688 +eugenio_finardi;2689 +extreme;2690 +foghat;2691 +george_thorogood_the_destroyers;2692 +great_white;2693 +guardian;2694 +jethro_tull;2695 +ian_anderson;2696 +david_knopfler;2697 +steppenwolf;2698 +dave_edmunds;2699 +lynyrd_skynyrd;2700 +crosby_stills_nash;2701 +raul_seixas;2702 +the_poodles;2703 +musiq_soulchild;2704 +shocking_blue;2705 +nick_lowe;2706 +the_black_crowes;2707 +traffic;2708 +widespread_panic;2709 +co;2710 +alberto_cortez;2711 +joan_sebastian;2712 +ana_gabriel;2713 +gilberto_santa_rosa;2714 +rub_n_blades;2715 +v_ctor_manuelle;2716 +celia_cruz;2717 +luis_fonsi;2718 +nek;2719 +dr_feelgood;2720 +astrud_gilberto;2721 +benito_di_paula;2722 +brazzaville;2723 +sacha_distel;2724 +chico_buarque;2725 +elis_regina;2726 +milton_nascimento;2727 +faf_de_bel_m;2728 +nikka_costa;2729 +tim_maia;2730 +gilberto_gil;2731 +lisa_ekdahl;2732 +joyce;2733 +maria_rita;2734 +nara_le_o;2735 +nouvelle_vague;2736 +paulinho_moska;2737 +wilson_simonal;2738 +14_bis;2739 +arnaldo_antunes;2740 +biquini_cavad_o;2741 +cidade_negra;2742 +cpm_22;2743 +c_ssia_eller;2744 +os_paralamas_do_sucesso;2745 +guilherme_arantes;2746 +ira;2747 +lob_o;2748 +nenhum_de_n_s;2749 +djavan;2750 +rog_rio_skylab;2751 +roupa_nova;2752 +ultraje_a_rigor;2753 +kj_52;2754 +amado_batista;2755 +chit_ozinho_xoror;2756 +jo_o_paulo_daniel;2757 +leandro_leonardo;2758 +leonardo;2759 +odair_jos;2760 +kaiser_chiefs;2761 +kula_shaker;2762 +lightning_seeds;2763 +pulp;2764 +the_proclaimers;2765 +dying_fetus;2766 +napalm_death;2767 +nile;2768 +pathology;2769 +hilary_duff;2770 +badly_drawn_boy;2771 +federico_salvatore;2772 +i_gufi;2773 +zachary_richard;2774 +stan_rogers;2775 +moxy_fr_vous;2776 +poco;2777 +la_bottine_souriante;2778 +stompin_tom_connors;2779 +bersuit_vergarabat;2780 +las_pastillas_del_abuelo;2781 +george_lam;2782 +altan;2783 +clannad;2784 +blackmore_s_night;2785 +capercaillie;2786 +celtic_thunder;2787 +eluveitie;2788 +powerwolf;2789 +gaelic_storm;2790 +an_na;2791 +jon_anderson;2792 +the_dubliners;2793 +loreena_mckennitt;2794 +omnia;2795 +secret_garden;2796 +shaun_davey;2797 +roger_daltrey;2798 +the_corrs;2799 +los_tigres_del_norte;2800 +laurent_voulzy;2801 +the_kelly_family;2802 +wolfe_tones;2803 +alan_stivell;2804 +heather_alexander;2805 +kate_rusby;2806 +dropkick_murphys;2807 +great_big_sea;2808 +fiddler_s_green;2809 +heather_dale;2810 +runrig;2811 +the_waterboys;2812 +dougie_maclean;2813 +adriano_celentano;2814 +alain_chamfort;2815 +zazie;2816 +hamelen;2817 +tazenda;2818 +arno;2819 +arthur_h;2820 +boudewijn_de_groot;2821 +charles_trenet;2822 +claudio_baglioni;2823 +claudio_rocchi;2824 +fabrizio_de_andr;2825 +dalida;2826 +dana_winner;2827 +demis_roussos;2828 +esther_ofarim;2829 +eugenio_bennato;2830 +michel_berger;2831 +francis_cabrel;2832 +maxime_le_forestier;2833 +georges_moustaki;2834 +gianmaria_testa;2835 +gianni_morandi;2836 +gigliola_cinquetti;2837 +milva;2838 +gilbert_b_caud;2839 +ginette_reno;2840 +giuni_russo;2841 +guy_b_art;2842 +helena_vondr_kov;2843 +hugues_aufray;2844 +ivan_graziani;2845 +ivano_fossati;2846 +jacques_bertin;2847 +jean_ferrat;2848 +juliane_werding;2849 +julien_clerc;2850 +los_temerarios;2851 +katerine;2852 +leny_escudero;2853 +mathieu_chedid;2854 +luca_barbarossa;2855 +l_o_ferr;2856 +rosenstolz;2857 +marc_lavoine;2858 +massimo_bubola;2859 +mecano;2860 +mia_martini;2861 +michel_jonasz;2862 +michele_zarrillo;2863 +fiorello;2864 +nada;2865 +mercedes_sosa;2866 +nino_d_angelo;2867 +patrick_bruel;2868 +patty_pravo;2869 +pierre_bachelet;2870 +rainald_grebe;2871 +rapha_l;2872 +raphael;2873 +richard_anthony;2874 +roberto_murolo;2875 +ron;2876 +stefano_rosso;2877 +stephan_eicher;2878 +vasco_rossi;2879 +yves_duteil;2880 +yves_jamait;2881 +ang_lica;2882 +aaron_carter;2883 +barry_louis_polisar;2884 +yuri;2885 +cri_cri;2886 +hevisaurus;2887 +juice_leskinen;2888 +kidz_bop;2889 +mara_maravilha;2890 +destroyer;2891 +scorpions;2892 +obk;2893 +duncan_dhu;2894 +parry_gripp;2895 +sandy_junior;2896 +the_verve_pipe;2897 +the_verve;2898 +the_wiggles;2899 +veggietales;2900 +newsboys;2901 +steven_curtis_chapman;2902 +toro_y_moi;2903 +medi_val_b_bes;2904 +aaron_neville;2905 +bethel_music;2906 +apologetix;2907 +gaither_vocal_band;2908 +building_429;2909 +chris_tomlin;2910 +matt_maher;2911 +jerusalem;2912 +david_meece;2913 +debby_boone;2914 +elevation_worship;2915 +matt_redman;2916 +planetshakers;2917 +majesty;2918 +jump5;2919 +lecrae;2920 +michael_w_smith;2921 +bride;2922 +natalie_grant;2923 +the_lads;2924 +audio_adrenaline;2925 +paul_wilbur;2926 +psalmen_voor_nu;2927 +sawyer_brown;2928 +shane_shane;2929 +the_echoing_green;2930 +twila_paris;2931 +watch_tower_bible_and_tract_society;2932 +da_t_r_u_t_h;2933 +dc_talk;2934 +flame;2935 +grits;2936 +trip_lee;2937 +crystal_lewis;2938 +the_cross_movement;2939 +tobymac;2940 +vico_c;2941 +mormon_tabernacle_choir;2942 +august_burns_red;2943 +black_veil_brides;2944 +deliverance;2945 +opeth;2946 +die_happy;2947 +disciple;2948 +galactic_cowboys;2949 +haste_the_day;2950 +living_sacrifice;2951 +mastodon;2952 +mortification;2953 +showbread;2954 +labyrinth;2955 +stryper;2956 +the_devil_wears_prada;2957 +underoath;2958 +whitecross;2959 +petra;2960 +huntingtons;2961 +mxpx;2962 +d_a_d;2963 +caedmon_s_call;2964 +david_and_the_giants;2965 +degarmo_and_key;2966 +delirious;2967 +don_francisco;2968 +five_iron_frenzy;2969 +geoff_moore;2970 +hawk_nelson;2971 +grave;2972 +larry_norman;2973 +randy_stonehill;2974 +monty_python;2975 +oomph;2976 +oficina_g3;2977 +white_heart;2978 +rescate;2979 +rick_wakeman;2980 +la_oreja_de_van_gogh;2981 +sanctus_real;2982 +fun_people;2983 +thousand_foot_krutch;2984 +tim_hughes;2985 +the_o_c_supertones;2986 +4him;2987 +billy_gilman;2988 +aimee_mann;2989 +katharine_mcphee;2990 +eros_ramazzotti;2991 +z_ro;2992 +babbie_mason;2993 +bebo_norman;2994 +judy_garland;2995 +carman;2996 +cece_winans;2997 +trick_daddy;2998 +chris_isaak;2999 +cocteau_twins;3000 +edyta_g_rniak;3001 +enrico_ruggeri;3002 +ffh;3003 +hanson;3004 +hawksley_workman;3005 +indigo_girls;3006 +irene_grandi;3007 +jackie_evancho;3008 +joy_electric;3009 +kelly_price;3010 +mary_mary;3011 +israel_houghton;3012 +phil_wickham;3013 +phillips_craig_dean;3014 +roch_voisine;3015 +rupaul;3016 +gregorian;3017 +sarah_connor;3018 +sugarland;3019 +sweetbox;3020 +tarja;3021 +the_brian_setzer_orchestra;3022 +brian_setzer;3023 +badfinger;3024 +the_moffatts;3025 +the_vandals;3026 +trans_siberian_orchestra;3027 +roy_drusky;3028 +burton_cummings;3029 +procol_harum;3030 +renaissance;3031 +the_pretty_things;3032 +twisted_sister;3033 +bj_rn_eidsv_g;3034 +corvus_corax;3035 +schelmish;3036 +emilie_autumn;3037 +epica;3038 +katherine_jenkins;3039 +scala_kolacny_brothers;3040 +take_6;3041 +the_roches;3042 +tony_banks;3043 +to_e_proeski;3044 +lacrimosa;3045 +16_volt;3046 +bj_rn_rosenstr_m;3047 +bob_rivers;3048 +cledus_t_judd;3049 +frankjavcee;3050 +george_formby;3051 +ninja_sex_party;3052 +paul_and_storm;3053 +the_arrogant_worms;3054 +tripod;3055 +el_cuarteto_de_nos;3056 +gwar;3057 +knorkator;3058 +psychostick;3059 +rodgau_monotones;3060 +los_palominos;3061 +charlie_peacock;3062 +jesus_culture;3063 +michael_card;3064 +tenth_avenue_north;3065 +carrie_newcomer;3066 +nick_drake;3067 +aaron_watson;3068 +billy_joe_royal;3069 +billy_joe_shaver;3070 +charlie_landsborough;3071 +chris_ledoux;3072 +collin_raye;3073 +dan_seals;3074 +dave_dudley;3075 +hellbillies;3076 +ed_bruce;3077 +emilio_navaira;3078 +jean_shepard;3079 +freddie_hart;3080 +gary_stewart;3081 +gene_watson;3082 +gian_giovani;3083 +gilberto_gilmar;3084 +jason_mraz;3085 +ilse_delange;3086 +john_prine;3087 +jake_owen;3088 +wynn_stewart;3089 +jim_ed_brown;3090 +joe_ely;3091 +kid_rock;3092 +la_toya_jackson;3093 +lit;3094 +lita_ford;3095 +me_first_and_the_gimme_gimmes;3096 +lagwagon;3097 +melanie;3098 +mickey_newbury;3099 +paul_brunelle;3100 +paula_fernandes;3101 +zez_di_camargo_luciano;3102 +randy_rogers_band;3103 +reverend_horton_heat;3104 +rick_renner;3105 +rionegro_solim_es;3106 +shooter_jennings;3107 +terri_clark;3108 +vern_gosdin;3109 +webb_wilder;3110 +ween;3111 +38_special;3112 +the_beau_brummels;3113 +matanza;3114 +clawfinger;3115 +acid_drinkers;3116 +agnostic_front;3117 +biohazard;3118 +body_count;3119 +d_r_i;3120 +municipal_waste;3121 +neurosis;3122 +nuclear_assault;3123 +soziedad_alkoholika;3124 +suicidal_tendencies;3125 +paragon;3126 +mario;3127 +inna;3128 +belinda;3129 +bronco;3130 +grupo_bryndis;3131 +david_bisbal;3132 +ram_n_ayala;3133 +grant_lee_phillips;3134 +the_veronicas;3135 +amr_diab;3136 +atb;3137 +basshunter;3138 +dream_theater;3139 +frankie_j;3140 +baby_bash;3141 +sophie_ellis_bextor;3142 +grace_jones;3143 +laveerre;3144 +silkk_the_shocker;3145 +parov_stelar;3146 +raffaella_carr;3147 +elephant_man;3148 +saint_etienne;3149 +samantha_fox;3150 +selena;3151 +super_junior;3152 +t_a_t_u;3153 +tarkan;3154 +judie_tzuke;3155 +el_kel_iset;3156 +yello;3157 +franz_ferdinand;3158 +chenoa;3159 +lucero;3160 +tokio;3161 +puffy_amiyumi;3162 +wink;3163 +obie_trice;3164 +mystikal;3165 +current_93;3166 +dark_sanctuary;3167 +rome;3168 +lord_of_the_lost;3169 +bella_morte;3170 +mantus;3171 +blutengel;3172 +clan_of_xymox;3173 +dead_can_dance;3174 +death_in_june;3175 +diary_of_dreams;3176 +diorama;3177 +helium_vola;3178 +illuminate;3179 +l_me_immortelle;3180 +lacrimas_profundere;3181 +killing_joke;3182 +m_nchener_freiheit;3183 +otto_dix;3184 +project_pitchfork;3185 +qntal;3186 +sopor_aeternus;3187 +the_cr_xshadows;3188 +unheilig;3189 +welle;3190 +yendri;3191 +carcass;3192 +asphyx;3193 +bolt_thrower;3194 +darkseed;3195 +paradise_lost;3196 +tiamat;3197 +the_damned;3198 +pantera;3199 +the_amity_affliction;3200 +judas_priest;3201 +amon_amarth;3202 +alesana;3203 +atrocity;3204 +autopsy;3205 +avulsed;3206 +sabaton;3207 +misfits;3208 +iron_fire;3209 +centinex;3210 +dagoba;3211 +dark_tranquillity;3212 +asia;3213 +deicide;3214 +dethklok;3215 +dew_scented;3216 +edge_of_sanity;3217 +escape_the_fate;3218 +heaven_shall_burn;3219 +hypocrisy;3220 +incantation;3221 +jungle_rot;3222 +kataklysm;3223 +krisiun;3224 +macabre;3225 +malevolent_creation;3226 +meshuggah;3227 +misanthrope;3228 +morbid_angel;3229 +dead_kennedys;3230 +necro;3231 +pig_destroyer;3232 +shadows_fall;3233 +sinister;3234 +six_feet_under;3235 +dream_evil;3236 +soulfly;3237 +the_black_dahlia_murder;3238 +between_the_buried_and_me;3239 +therion;3240 +vader;3241 +whitechapel;3242 +attila;3243 +emmure;3244 +miss_may_i;3245 +the_acacia_strain;3246 +betontod;3247 +broilers;3248 +dritte_wahl;3249 +ohl;3250 +slime;3251 +terrorgruppe;3252 +b_hse_onkelz;3253 +frei_wild;3254 +k_rbholz;3255 +asp;3256 +tokio_hotel;3257 +queensr_che;3258 +amanda_miguel;3259 +arabesque;3260 +bad_boys_blue;3261 +boyce_avenue;3262 +parliament;3263 +wu_tang_clan;3264 +neoton_fam_lia;3265 +teena_marie;3266 +bobby_womack;3267 +agoraphobic_nosebleed;3268 +candlemass;3269 +electric_wizard;3270 +black_sabbath;3271 +theatre_of_tragedy;3272 +type_o_negative;3273 +marie_fredriksson;3274 +luna;3275 +marissa_nadler;3276 +yo_la_tengo;3277 +celldweller;3278 +hitomi;3279 +big_d_and_the_kids_table;3280 +alacranes_musical;3281 +k_paz_de_la_sierra;3282 +assemblage_23;3283 +covenant;3284 +die_krupps;3285 +kodak_black;3286 +front_242;3287 +haujobb;3288 +in_strict_confidence;3289 +le_ther_strip;3290 +snog;3291 +the_darkness;3292 +tanzwut;3293 +terminal_choice;3294 +velvet_acid_christ;3295 +vnv_nation;3296 +wumpscut;3297 +x_fusion;3298 +umbra_et_imago;3299 +de_vision;3300 +deichkind;3301 +eisbrecher;3302 +herbie_hancock;3303 +ana_moura;3304 +macaco;3305 +skinny_puppy;3306 +ayreon;3307 +black_moth_super_rainbow;3308 +erykah_badu;3309 +cocorosie;3310 +de_jeugd_van_tegenwoordig;3311 +dj_shadow;3312 +e_nomine;3313 +kmfdm;3314 +flying_lotus;3315 +goldfrapp;3316 +hanzel_und_gretyl;3317 +information_society;3318 +mc_frontalot;3319 +kraftwerk;3320 +ladytron;3321 +lamb;3322 +milk_inc;3323 +mind_in_a_box;3324 +ministry;3325 +m_m;3326 +m_nia;3327 +pig;3328 +pitchshifter;3329 +lil_boosie;3330 +master_p;3331 +mindless_self_indulgence;3332 +buzzcocks;3333 +vanilla_ice;3334 +milie_simon;3335 +gianna_nannini;3336 +pinback;3337 +the_birthday_massacre;3338 +archive;3339 +99_posse;3340 +bloc_party;3341 +morcheeba;3342 +origa;3343 +paul_kalkbrenner;3344 +tina_arena;3345 +dover;3346 +melotron;3347 +owl_city;3348 +kamelot;3349 +greeley_estates;3350 +hawthorne_heights;3351 +joan_of_arc;3352 +saves_the_day;3353 +thursday;3354 +transit;3355 +fairport_convention;3356 +maggie_reilly;3357 +joan_manuel_serrat;3358 +e_rotic;3359 +the_scene;3360 +sandra;3361 +amon_d_l_ii;3362 +circa_survive;3363 +love_solfege;3364 +caliban;3365 +tall_dwarfs;3366 +van_der_graaf_generator;3367 +death_grips;3368 +the_fiery_furnaces;3369 +am_lia_rodrigues;3370 +cristina_branco;3371 +jos_afonso;3372 +katia_guerreiro;3373 +ney_matogrosso;3374 +madredeus;3375 +mariza;3376 +gipsy_kings;3377 +mal;3378 +aleks_syntek;3379 +ni_a_pastori;3380 +rosario;3381 +al_stewart;3382 +amos_lee;3383 +andr_s_calamaro;3384 +ane_brun;3385 +asa;3386 +editors;3387 +catie_curtis;3388 +chrystian_ralf;3389 +clueso;3390 +eddi_reader;3391 +eddie_from_ohio;3392 +ellis_paul;3393 +frank_turner;3394 +estampie;3395 +ferdi_tayfur;3396 +fito_p_ez;3397 +luis_alberto_spinetta;3398 +gabriella_ferri;3399 +gigi;3400 +greg_brown;3401 +g_ksel;3402 +lando_fiorini;3403 +india_arie;3404 +jack_savoretti;3405 +anne_grete_preus;3406 +jarom_r_nohavica;3407 +joe_purdy;3408 +john_wesley_harding;3409 +josh_rouse;3410 +karel_kryl;3411 +v_tor_ramil;3412 +lars_winnerb_ck;3413 +laura_marling;3414 +llu_s_llach;3415 +los_chalchaleros;3416 +luka_bloom;3417 +malicorne;3418 +mark_heard;3419 +martin_carthy;3420 +nic_jones;3421 +le_n_gieco;3422 +mijares;3423 +nuova_compagnia_di_canto_popolare;3424 +ola_magnell;3425 +thin_lizzy;3426 +ray_lamontagne;3427 +ron_sexsmith;3428 +rosana;3429 +silvio_rodr_guez;3430 +stef_bos;3431 +sun_kil_moon;3432 +tanita_tikaram;3433 +the_incredible_string_band;3434 +thea_gilmore;3435 +tina_dico;3436 +victor_leo;3437 +v_rttin;3438 +ge_aleksandersen;3439 +i_brahim_tatl_ses;3440 +ektomorf;3441 +elvenking;3442 +ensiferum;3443 +falconer;3444 +feuerschwanz;3445 +in_extremo;3446 +korpiklaani;3447 +leaves_eyes;3448 +letzte_instanz;3449 +m_go_de_oz;3450 +saurom;3451 +schandmaul;3452 +skyclad;3453 +subway_to_sally;3454 +suidakra;3455 +t_r;3456 +icehouse;3457 +bomb_the_music_industry;3458 +the_real_mckenzies;3459 +54_40;3460 +armored_saint;3461 +alexz_johnson;3462 +bar_man_o;3463 +ezginin_g_nl;3464 +galija;3465 +sts;3466 +h_kan_hellstr_m;3467 +james_blunt;3468 +kazik;3469 +mewithoutyou;3470 +michel_polnareff;3471 +ovidi_montllor;3472 +rasputina;3473 +shearwater;3474 +gerry_rafferty;3475 +steam_powered_giraffe;3476 +the_saw_doctors;3477 +ty_segall;3478 +tyrone_wells;3479 +avi_es_do_forr;3480 +grimskunk;3481 +sinik;3482 +vitaa;3483 +kenza_farah;3484 +sexion_d_assaut;3485 +aliz_e;3486 +henri_tachan;3487 +jenifer;3488 +m_pokora;3489 +indochine;3490 +brainstorm;3491 +con_funk_shun;3492 +funkadelic;3493 +lena_park;3494 +neffa;3495 +ugk;3496 +suburban_legends;3497 +mai_kuraki;3498 +cherry_poppin_daddies;3499 +electric_six;3500 +los_straitjackets;3501 +the_69_eyes;3502 +the_angels;3503 +the_haunted;3504 +the_hellacopters;3505 +the_kills;3506 +thee_oh_sees;3507 +white_denim;3508 +zabranjeno_pu_enje;3509 +ol_dirty_bastard;3510 +kurupt;3511 +spice_1;3512 +brotha_lynch_hung;3513 +chamillionaire;3514 +paul_wall;3515 +trae;3516 +club_dogo;3517 +mc_eiht;3518 +royce_da_5_9;3519 +geto_boys;3520 +the_diplomats;3521 +ice_t;3522 +2_live_crew;3523 +xv;3524 +mobb_deep;3525 +c_murder;3526 +tru;3527 +lil_keke;3528 +project_pat;3529 +tha_dogg_pound;3530 +esham;3531 +twiztid;3532 +erick_sermon;3533 +big_tymers;3534 +kate_nash;3535 +the_cramps;3536 +nekromantix;3537 +tsol;3538 +ace_frehley;3539 +hardcore_superstar;3540 +harem_scarem;3541 +house_of_lords;3542 +kingdom_come;3543 +l_a_guns;3544 +mr_big;3545 +pink_cream_69;3546 +quiet_riot;3547 +riot;3548 +ratt;3549 +tnt;3550 +backyard_babies;3551 +ultima_thule;3552 +europe;3553 +hanoi_rocks;3554 +mott_the_hoople;3555 +smokie;3556 +suzi_quatro;3557 +haemorrhage;3558 +aline_barros;3559 +bruna_karla;3560 +kirk_franklin;3561 +minist_rio_koinonya_de_louvor;3562 +artrosis;3563 +closterkeller;3564 +indica;3565 +sirenia;3566 +trail_of_tears;3567 +tristania;3568 +within_temptation;3569 +bauhaus;3570 +mono_inc;3571 +pansy_division;3572 +xandria;3573 +immortal_technique;3574 +agathocles;3575 +rotten_sound;3576 +the_locust;3577 +anthrax;3578 +devildriver;3579 +lamb_of_god;3580 +machine_head;3581 +parkway_drive;3582 +pro_pain;3583 +throwdown;3584 +vicious_rumors;3585 +screaming_trees;3586 +cuisillos;3587 +intocable;3588 +pesado;3589 +la_mafia;3590 +marco_antonio_sol_s;3591 +los_bukis;3592 +andrew_w_k;3593 +april_wine;3594 +axel_rudi_pell;3595 +b_z;3596 +tak_matsumoto;3597 +barricada;3598 +bijelo_dugme;3599 +blaze_bayley;3600 +bonfire;3601 +bruce_dickinson;3602 +buckcherry;3603 +budgie;3604 +buitres;3605 +jorn;3606 +doro;3607 +enuff_z_nuff;3608 +gentle_giant;3609 +girlschool;3610 +golden_earring;3611 +gotthard;3612 +nazareth;3613 +a_day_to_remember;3614 +jefferson_airplane;3615 +joe_satriani;3616 +ken_hensley;3617 +kim_mitchell;3618 +king_s_x;3619 +kotiteollisuus;3620 +la_renga;3621 +lee_aaron;3622 +lordi;3623 +michael_schenker_group;3624 +mustasch;3625 +night_ranger;3626 +omega;3627 +parni_valjak;3628 +paul_gilbert;3629 +popeda;3630 +skid_row;3631 +tankcsapda;3632 +the_bronx;3633 +the_donnas;3634 +all_that_remains;3635 +triumph;3636 +umphrey_s_mcgee;3637 +y_t;3638 +ziggy;3639 +sfdk;3640 +7_seconds;3641 +aiden;3642 +alphaville;3643 +black_flag;3644 +slayer;3645 +circle_jerks;3646 +ritchie;3647 +converge;3648 +every_time_i_die;3649 +hatebreed;3650 +nomeansno;3651 +rancid;3652 +memphis_may_fire;3653 +nofx;3654 +propagandhi;3655 +tankard;3656 +screeching_weasel;3657 +sick_of_it_all;3658 +silverstein;3659 +two_steps_from_hell;3660 +faun;3661 +accept;3662 +the_frames;3663 +andromeda;3664 +annihilator;3665 +anvil;3666 +artillery;3667 +avenged_sevenfold;3668 +axxis;3669 +blind_guardian;3670 +vanden_plas;3671 +grave_digger;3672 +dragonforce;3673 +edenbridge;3674 +damien_jurado;3675 +exciter;3676 +firewind;3677 +halford;3678 +hammerfall;3679 +helloween;3680 +helstar;3681 +iced_earth;3682 +jag_panzer;3683 +machinae_supremacy;3684 +manowar;3685 +metal_church;3686 +morgana_lefay;3687 +mudvayne;3688 +nocturnal_rites;3689 +overkill;3690 +primal_fear;3691 +rebellion;3692 +running_wild;3693 +corey_hart;3694 +savatage;3695 +saxon;3696 +steve_vai;3697 +tad_morose;3698 +tarot;3699 +tierra_santa;3700 +trivium;3701 +turmion_k_til_t;3702 +u_d_o;3703 +virgin_steele;3704 +voivod;3705 +warcry;3706 +yngwie_malmsteen;3707 +zion_lennox;3708 +sido;3709 +mc_chris;3710 +assalti_frontali;3711 +kool_keith;3712 +ayumi_hamasaki;3713 +az;3714 +bahh_tee;3715 +bassi_maestro;3716 +revocation;3717 +blumentopf;3718 +brockhampton;3719 +bts;3720 +bushido;3721 +vinnie_paz;3722 +chakuza;3723 +cheek;3724 +cro;3725 +arc_ngel;3726 +alexis_fido;3727 +dargen_d_amico;3728 +the_coup;3729 +def_con_dos;3730 +die_fantastischen_vier;3731 +dom_no;3732 +donguralesko;3733 +epmd;3734 +kool_savas;3735 +fettes_brot;3736 +fronda;3737 +mc_solaar;3738 +pyhimys;3739 +kaaris;3740 +kollegah;3741 +kontra_k;3742 +k_k;3743 +l_o_c;3744 +logic;3745 +jerry_rivera;3746 +murs;3747 +angie_stone;3748 +namie_amuro;3749 +anthony_hamilton;3750 +lyfe_jennings;3751 +bl_f;3752 +o_s_t_r;3753 +paluch;3754 +parazi_ii;3755 +porta;3756 +bleeding_through;3757 +prinz_pi;3758 +rasmentalism;3759 +xavier_naidoo;3760 +sage_francis;3761 +stupeflip;3762 +young_thug;3763 +tego_calder_n;3764 +fifth_harmony;3765 +jay_chou;3766 +blitzkid;3767 +zumbis_do_espa_o;3768 +deer_tick;3769 +half_man_half_biscuit;3770 +hayden;3771 +club_8;3772 +grandaddy;3773 +jens_lekman;3774 +kent;3775 +keren_ann;3776 +los_campesinos;3777 +nellie_mckay;3778 +china_crisis;3779 +prefab_sprout;3780 +the_clientele;3781 +the_lucksmiths;3782 +bell_x1;3783 +british_sea_power;3784 +car_seat_headrest;3785 +deerhunter;3786 +dr_dog;3787 +elf_power;3788 +frightened_rabbit;3789 +fugazi;3790 +fury_in_the_slaughterhouse;3791 +julie_doiron;3792 +tinashe;3793 +la_habitaci_n_roja;3794 +margot_the_nuclear_so_and_so_s;3795 +matt_pond_pa;3796 +metric;3797 +mike_doughty;3798 +mother_mother;3799 +piebald;3800 +quasi;3801 +rheostatics;3802 +sebadoh;3803 +spoon;3804 +starflyer_59;3805 +stephen_malkmus;3806 +stereolab;3807 +ted_leo_and_the_pharmacists;3808 +the_appleseed_cast;3809 +the_faint;3810 +the_go_betweens;3811 +the_pineapple_thief;3812 +the_undertones;3813 +tronic;3814 +chris_de_burgh;3815 +mass_hysteria;3816 +angelo_branduardi;3817 +gigi_d_alessio;3818 +i_muvrini;3819 +back_number;3820 +boa;3821 +claris;3822 +crystal_kay;3823 +zard;3824 +gackt;3825 +garnet_crow;3826 +girls_generation;3827 +kat_tun;3828 +koda_kumi;3829 +kotoko;3830 +lisa;3831 +maaya_sakamoto;3832 +masami_okui;3833 +mr_children;3834 +news;3835 +shinee;3836 +w_inds;3837 +yui;3838 +yumi_matsutoya;3839 +the_high_lows;3840 +sid;3841 +abbey_lincoln;3842 +anna_maria_jopek;3843 +cassandra_wilson;3844 +dianne_reeves;3845 +fred_buscaglione;3846 +jane_monheit;3847 +zor_n;3848 +kraan;3849 +laura_fygi;3850 +michael_franks;3851 +natalino_otto;3852 +quartetto_cetra;3853 +scott_bradlee_s_postmodern_jukebox;3854 +stacey_kent;3855 +the_flower_kings;3856 +ronnie_von;3857 +brown_eyed_girls;3858 +ahmet_kaya;3859 +alejandra_guzm_n;3860 +ana_carolina;3861 +alcione;3862 +el_chapo_de_sinaloa;3863 +gustavo_cerati;3864 +soda_stereo;3865 +jenni_rivera;3866 +joaqu_n_sabina;3867 +los_fabulosos_cadillacs;3868 +abel_pintos;3869 +ana_bel_n;3870 +aterciopelados;3871 +camilo_sesto;3872 +david_demar_a;3873 +gian_marco;3874 +menudo;3875 +ricardo_arjona;3876 +sabroso;3877 +v_ctor_manuel;3878 +las_pelotas;3879 +ariel_pink;3880 +leehom_wang;3881 +jolin_tsai;3882 +darkest_hour;3883 +kalmah;3884 +nightrage;3885 +eppu_normaali;3886 +the_outfield;3887 +no_use_for_a_name;3888 +pennywise;3889 +callejon;3890 +d_f_c;3891 +our_last_night;3892 +exaltasamba;3893 +beth_carvalho;3894 +jo_o_bosco;3895 +marina_lima;3896 +marisa_monte;3897 +nando_reis;3898 +natiruts;3899 +ra_a_negra;3900 +s_pra_contrariar;3901 +zeca_pagodinho;3902 +andr_hazes;3903 +de_dijk;3904 +arena;3905 +iq;3906 +sol_invictus;3907 +new_found_glory;3908 +adam_ant;3909 +berlin;3910 +hoodoo_gurus;3911 +ultravox;3912 +nik_kershaw;3913 +squeeze;3914 +the_aquabats;3915 +the_fixx;3916 +beat_crusaders;3917 +cows;3918 +conjunto_primavera;3919 +peter_and_the_test_tube_babies;3920 +sham_69;3921 +the_adicts;3922 +the_analogs;3923 +instalok;3924 +jacek_kaczmarski;3925 +przemys_aw_gintrowski;3926 +ada_band;3927 +agnetha_f_ltskog;3928 +ajda_pekkan;3929 +al_bano;3930 +alex_ubago;3931 +alison_moyet;3932 +alunni_del_sole;3933 +anna_oxa;3934 +bajm;3935 +barclay_james_harvest;3936 +blue_system;3937 +brunner_brunner;3938 +candan_er_etin;3939 +christian_bautista;3940 +clay_aiken;3941 +clifford_t_ward;3942 +daniel;3943 +don_backy;3944 +jesse_mccartney;3945 +emma;3946 +marcella_bella;3947 +giorgio_gaber;3948 +guus_meeuwis;3949 +heinz_rudolf_kunze;3950 +john_farnham;3951 +ian_thomas;3952 +i_n_karaca;3953 +jennifer_rush;3954 +jo_vally;3955 +john_fogerty;3956 +julian_lennon;3957 +k3;3958 +kid_abelha;3959 +labv_l_gais_tips;3960 +l_vi;3961 +lea_salonga;3962 +les_wampas;3963 +magnus_uggla;3964 +mango;3965 +maria_mena;3966 +massimo_ranieri;3967 +max_gazz;3968 +michael_learns_to_rock;3969 +mietta;3970 +mustafa_sandal;3971 +nil_fer;3972 +peter_frampton;3973 +pr_ta_v_tra;3974 +pur;3975 +rettore;3976 +ricchi_e_poveri;3977 +rob_de_nijs;3978 +sara_bareilles;3979 +sasha;3980 +sertab_erener;3981 +sezen_aksu;3982 +stadio;3983 +stephen_sondheim;3984 +tamara;3985 +team_starkid;3986 +toto_cutugno;3987 +umberto_tozzi;3988 +herman_brood;3989 +wanessa;3990 +zen_caf;3991 +bonanza_banzai;3992 +bodyjar;3993 +bracket;3994 +frenzal_rhomb;3995 +goldfinger;3996 +the_wonder_years;3997 +useless_id;3998 +camel;3999 +hombres_g;4000 +leo_jaime;4001 +neal_morse;4002 +spock_s_beard;4003 +new_trolls;4004 +opus;4005 +piersi;4006 +premiata_forneria_marconi;4007 +superbus;4008 +zmelkoow;4009 +boysetsfire;4010 +hot_water_music;4011 +new_model_army;4012 +the_monochrome_set;4013 +big_big_train;4014 +avantasia;4015 +dark_moor;4016 +dreamtale;4017 +freedom_call;4018 +mystic_prophecy;4019 +nightmare;4020 +rhapsody_of_fire;4021 +royal_hunt;4022 +sonata_arctica;4023 +stratovarius;4024 +symphony_x;4025 +vision_divine;4026 +the_wildhearts;4027 +armia;4028 +evergrey;4029 +lana_lane;4030 +nektar;4031 +pain_of_salvation;4032 +riverside;4033 +beardfish;4034 +echolyn;4035 +eloy;4036 +john_wetton;4037 +medina_azahara;4038 +mostly_autumn;4039 +pendragon;4040 +rafo_r_ez;4041 +the_meteors;4042 +against_me;4043 +anti_flag;4044 +banda_bassotti;4045 +cadena_perpetua;4046 +descendents;4047 +distemper;4048 +dogwood;4049 +el_ltimo_ke_zierre;4050 +farben_lehre;4051 +toy_dolls;4052 +junkies;4053 +ksu;4054 +la_polla_records;4055 +la_vela_puerca;4056 +leatherface;4057 +less_than_jake;4058 +mad_caddies;4059 +millencolin;4060 +punkreas;4061 +reel_big_fish;4062 +snfu;4063 +stiff_little_fingers;4064 +swingin_utters;4065 +the_bouncing_souls;4066 +the_casualties;4067 +the_dickies;4068 +the_lawrence_arms;4069 +toyah;4070 +gerald_levert;4071 +gondwana;4072 +los_aut_nticos_decadentes;4073 +los_cafres;4074 +los_pericos;4075 +tryo;4076 +rakim_ken_y;4077 +billy_squier;4078 +bj_rn_afzelius;4079 +glay;4080 +hunters_collectors;4081 +john_entwistle;4082 +jokke;4083 +la_beriso;4084 +los_rancheros;4085 +los_tres;4086 +maanam;4087 +mikel_erentxun;4088 +peter_wolf;4089 +racoon;4090 +rev_lver;4091 +riblja_orba;4092 +sandro;4093 +gene_vincent;4094 +the_baseballs;4095 +stray_cats;4096 +as_marcianas;4097 +bruno_marrone;4098 +cristiano_ara_jo;4099 +fernando_sorocaba;4100 +joint_venture;4101 +serge_reggiani;4102 +ska_p;4103 +the_mighty_mighty_bosstones;4104 +fu_manchu;4105 +jay_jay_johanson;4106 +psyche;4107 +carlos_gardel;4108 diff --git a/jukebox/data/ids/v2_genre_ids.txt b/jukebox/data/ids/v2_genre_ids.txt new file mode 100644 index 0000000000000000000000000000000000000000..39adb96a85bc3b08ce68f33fb9ead3d76b7e2aef --- /dev/null +++ b/jukebox/data/ids/v2_genre_ids.txt @@ -0,0 +1,120 @@ +unknown;0 +classical;1 +blues;2 +hip;3 +hop;4 +dance;5 +soul;6 +hard;7 +rock;8 +jazz;9 +reggae;10 +country;11 +alternative;12 +soundtrack;13 +pop;14 +bluegrass;15 +vocal;16 +r;17 +b;18 +rap;19 +christian;20 +gospel;21 +electronic;22 +christmas;23 +singer;24 +songwriter;25 +metal;26 +n;27 +roll;28 +synthpop;29 +electronica;30 +mpb;31 +movie;32 +indie;33 +new;34 +wave;35 +electro;36 +house;37 +folk;38 +punk;39 +french;40 +contemporary;41 +garage;42 +soft;43 +acoustic;44 +nu;45 +television;46 +post;47 +eurodance;48 +progressive;49 +gothic;50 +classic;51 +funk;52 +disco;53 +swing;54 +trance;55 +thrash;56 +psychedelic;57 +heavy;58 +american;59 +grunge;60 +art;61 +j;62 +gangsta;63 +brazilian;64 +latin;65 +southern;66 +ska;67 +crossover;68 +hardcore;69 +industrial;70 +glam;71 +melodic;72 +ambient;73 +musical;74 +dream;75 +experimental;76 +americana;77 +chanson;78 +rockabilly;79 +britpop;80 +children;81 +s;82 +music;83 +electropop;84 +power;85 +celtic;86 +dark;87 +comedy;88 +doom;89 +trip;90 +lo;91 +fi;92 +metalcore;93 +symphonic;94 +fado;95 +schlager;96 +avant;97 +garde;98 +europop;99 +reggaeton;100 +emo;101 +death;102 +samba;103 +deathcore;104 +black;105 +horrorcore;106 +grindcore;107 +worship;108 +salsa;109 +ebm;110 +neofolk;111 +sertanejo;112 +deutschrock;113 +norte;114 +o;115 +ax;116 +k;117 +tejano;118 +medieval;119 diff --git a/jukebox/data/ids/v3_artist_ids.txt b/jukebox/data/ids/v3_artist_ids.txt new file mode 100644 index 0000000000000000000000000000000000000000..9987bb6e676b015ca5b3a7a0d234e69b171dd4cc --- /dev/null +++ b/jukebox/data/ids/v3_artist_ids.txt @@ -0,0 +1,7898 @@ +beat farmers;1 +aaron sprinkle;2 +dianne reeves;3 +lowe;4 +harry manx;5 +hail of bullets;6 +ian gillan;7 +andraé crouch;8 +widespread panic;9 +buddy wasisname and the other fellers;10 +misery index;11 +albert west;12 +shadowland;13 +homer & jethro;14 +damien jurado;15 +dead to fall;16 +british sea power;17 +pam tillis;18 +ice cube;19 +hey rosetta!;20 +sophie zelmani;21 +riverside;22 +head automatica;23 +diabulus in musica;24 +unitopia;25 +revolting cocks;26 +zita swoon;27 +train;28 +ken stringfellow;29 +in dying arms;30 +red lorry yellow lorry;31 +small faces;32 +michael sweet;33 +30 odd foot of grunts;34 +white heart;35 +baby bash;36 +bad bones;37 +meat beat manifesto;38 +vengeance;39 +naomi;40 +koritni;41 +the fall of troy;42 +split enz;43 +emmy rossum;44 +les fleur de lys;45 +beaux arts trio;46 +david crowder band;47 +mojave 3;48 +girl talk;49 +motorpsycho;50 +burning point;51 +the rutles;52 +david and the giants;53 +jinjer;54 +sitd;55 +pedro the lion;56 +masta ace;57 +alexz johnson;58 +the floacist;59 +after 7;60 +anointed;61 +holy soldier;62 +sanchez;63 +wovenhand;64 +thea gilmore;65 +3t;66 +patty loveless;67 +ghost;68 +rie fu;69 +chemical vocation;70 +robbie nevil;71 +the notorious b.i.g.;72 +america;73 +the boo radleys;74 +in hearts wake;75 +jack the lad;76 +gerry and the pacemakers;77 +he is we;78 +cuban link;79 +galaxie 500;80 +something with numbers;81 +the last shadow puppets;82 +minor threat;83 +joss stone;84 +lynch mob;85 +zino francescatti;86 +genitorturers;87 +kenny g;88 +graveworm;89 +field mob;90 +opus;91 +jordan smith;92 +sheppard;93 +the haunted;94 +tiny ruins;95 +jimmy somerville;96 +acid reign;97 +falling in reverse;98 +ace troubleshooter;99 +josh groban;100 +adriano celentano;101 +john oates;102 +mind funk;103 +christafari;104 +clan of xymox;105 +anti-flag;106 +the blow monkeys;107 +the troggs;108 +priscilla ahn;109 +fastball;110 +raekwon;111 +royal wood;112 +agoraphobic nosebleed;113 +borknagar;114 +parker millsap;115 +kelly osbourne;116 +psyche;117 +brokencyde;118 +george clinton;119 +the hollies;120 +gabriel kahane;121 +dnce;122 +jimmy nail;123 +harem scarem;124 +pierre fournier;125 +gideon;126 +elitist;127 +the sheepdogs;128 +like moths to flames;129 +the constructus corporation;130 +impending doom;131 +joe williams;132 +bizzy bone;133 +nelson;134 +earth and fire;135 +underoath;136 +rancid;137 +exile;138 +vertical horizon;139 +percy sledge;140 +ill bill;141 +59 times the pain;142 +jimmy dean;143 +gary jules;144 +spellblast;145 +renee olstead;146 +barbra streisand;147 +spin doctors;148 +galt macdermot;149 +takara;150 +alan stivell;151 +andy davis;152 +babes in toyland;153 +still remains;154 +the donnas;155 +bishop allen;156 +the skids;157 +rhiannon giddens;158 +natalia;159 +henson cargill;160 +gov't mule;161 +jools holland;162 +kehlani;163 +londonbeat;164 +andy mineo;165 +corky and the juice pigs;166 +days away;167 +a fine frenzy;168 +roger mcguinn;169 +lena horne;170 +shark island;171 +machinemade god;172 +yank rachell;173 +hurricane;174 +his statue falls;175 +that petrol emotion;176 +764-hero;177 +leprous;178 +bridgit mendler;179 +beggars opera;180 +abbie gale;181 +the the;182 +y'akoto;183 +sound tesselated;184 +webb pierce;185 +river whyless;186 +ronnie dio & the prophets;187 +rotting christ;188 +duff mckagan;189 +slim harpo;190 +adele;191 +valencia;192 +the damned;193 +miguel;194 +chantal kreviazuk;195 +the db's;196 +cartel;197 +enrique iglesias;198 +skrewdriver;199 +one less reason;200 +lil wayne;201 +chris norman;202 +type o negative;203 +trip shakespeare;204 +jack blanchard & misty morgan;205 +fishboy;206 +ted leo and the pharmacists;207 +lukas graham;208 +the vapors;209 +conway twitty & loretta lynn;210 +sandie shaw;211 +mark knopfler;212 +through the eyes of the dead;213 +art of dying;214 +free;215 +saint motel;216 +sonreal;217 +gatsbys american dream;218 +elisa;219 +marc anthony;220 +joan baez;221 +someone still loves you boris yeltsin;222 +ugk;223 +deep purple;224 +mother mother;225 +the contortionist;226 +hot chelle rae;227 +eric clapton;228 +the doobie brothers;229 +john michael montgomery;230 +izegrim;231 +jason collett;232 +close your eyes;233 +snog;234 +ghostpoet;235 +new order;236 +the brian setzer orchestra;237 +royal tusk;238 +guy mitchell;239 +heart;240 +the free design;241 +billie ray martin;242 +toto;243 +david mallett;244 +donovan;245 +the years gone by;246 +element 101;247 +fairyland;248 +triggerfinger;249 +mc eiht;250 +ottorino respighi;251 +the four aces;252 +lil son jackson;253 +emanuel feuermann;254 +juliette and the licks;255 +p!nk;256 +gretchen wilson;257 +the animals;258 +locksley;259 +redgum;260 +young mc;261 +metronomy;262 +ashland high;263 +esoteric;264 +johnny hates jazz;265 +paul anka;266 +ethel merman;267 +east west;268 +the knife;269 +curren$y;270 +maaya sakamoto;271 +aesthetic perfection;272 +bobby helms;273 +jimi jamison;274 +darren styles;275 +lorrie morgan;276 +miley cyrus;277 +dropdead;278 +dr. sin;279 +burt bacharach;280 +nf;281 +astronautalis;282 +garth brooks;283 +flyleaf;284 +lake;285 +mad sin;286 +tiffany evans;287 +mudvayne;288 +máni svavarsson & magnús scheving;289 +unexpect;290 +collin raye;291 +johnny reid;292 +antonio vivaldi;293 +creed;294 +burning heads;295 +legion of the damned;296 +matt costa;297 +the aluminum group;298 +orgy;299 +2nd chapter of acts;300 +shotgun messiah;301 +mentallo & the fixer;302 +urma;303 +carmen mcrae;304 +skid row;305 +john denver & the muppets;306 +angie stone;307 +rob rock;308 +clara haskil;309 +morandi;310 +team dresch;311 +the zombies;312 +mr. vegas;313 +royal trux;314 +suzanne vega;315 +the afters;316 +skydiggers;317 +sunday's best;318 +gary numan;319 +three dog night;320 +jonas brothers;321 +uncle acid & the deadbeats;322 +pablo de sarasate;323 +goretrade;324 +strapping young lad;325 +fat joe;326 +robert johnson;327 +fred astaire;328 +anastacia;329 +devendra banhart;330 +into it. over it.;331 +john norum;332 +cross canadian ragweed;333 +destroyer;334 +michael christmas;335 +phobia;336 +jill tracy;337 +dilana;338 +royce da 5'9";339 +les savy fav;340 +the blow;341 +kim wilde;342 +parts & labor;343 +dinah washington;344 +maggie reilly;345 +screaming trees;346 +p.o.s.;347 +atomic rooster;348 +chamillionaire;349 +the vaccines;350 +tides of man;351 +heathen;352 +flame;353 +brain drill;354 +ac/dc;355 +kraan;356 +scary kids scaring kids;357 +rosaline;358 +john legend;359 +of montreal;360 +the brunettes;361 +shelley fabares;362 +volumes;363 +george enescu;364 +jacob's dream;365 +heartless bastards;366 +darin;367 +andy stochansky;368 +david geringas;369 +lucius;370 +steep;371 +bobby vinton;372 +shania twain;373 +rudolf serkin;374 +the zolas;375 +municipal waste;376 +spectral;377 +arcade fire;378 +steve hillage;379 +the presets;380 +gustav mahler;381 +gary morris;382 +laura cantrell;383 +dean brody;384 +roger miller;385 +tammy wynette;386 +joe cocker;387 +iceage;388 +apostasy;389 +tait;390 +reverend gary davis;391 +neverending white lights;392 +mimicking birds;393 +barney;394 +major parkinson;395 +seal;396 +wham!;397 +tha dogg pound;398 +big l;399 +ian thomas;400 +kronos;401 +dom pachino;402 +dead can dance;403 +the number twelve looks like you;404 +bert williams;405 +bedhead;406 +scott bradlee's postmodern jukebox;407 +monuments;408 +christine mcvie;409 +moonspell;410 +david & the citizens;411 +*nsync;412 +tiny tim;413 +surface;414 +k.flay;415 +travis scott;416 +lil jon;417 +jo stafford;418 +elo part ii;419 +sugarland;420 +eternal;421 +the dingees;422 +the summer set;423 +soft machine;424 +maanam;425 +right said fred;426 +chicks on speed;427 +foetus;428 +fiona apple;429 +primer 55;430 +the dillinger escape plan;431 +seahaven;432 +biga ranx;433 +the insyderz;434 +thirty seconds to mars;435 +page france;436 +howlin' wolf;437 +wishbone ash;438 +nina sky;439 +jess moskaluke;440 +stan rogers;441 +b.o.b;442 +cypecore;443 +young dro;444 +julian lennon;445 +opeth;446 +flying lotus;447 +rodney atkins;448 +sea of treachery;449 +montrose;450 +nellie mckay;451 +vladimir horowitz;452 +fatboy slim;453 +mystic prophecy;454 +little river band;455 +brooklyn bounce;456 +destroid;457 +mary hopkin;458 +elliott yamin;459 +billy bragg;460 +the doors;461 +esham;462 +cab calloway;463 +thi'sl;464 +the gothsicles;465 +david coverdale;466 +joe henry;467 +the human abstract;468 +alger "texas" alexander;469 +diane cluck;470 +fozzy;471 +zero 7;472 +cole swindell;473 +gladys knight & the pips;474 +donna fargo;475 +cave in;476 +eiffel 65;477 +fates warning;478 +decrepit birth;479 +bad religion;480 +poison clan;481 +shane & shane;482 +johnny shines;483 +u.n.l.v.;484 +seth lakeman;485 +mindy smith;486 +josh white;487 +android lust;488 +mylon lefevre;489 +aselin debison;490 +kaskade;491 +the stills;492 +alpha blondy;493 +hughes turner project;494 +spice girls;495 +zz top;496 +fairport convention;497 +the ritchie family;498 +eleanor friedberger;499 +laura branigan;500 +the jordanaires;501 +the bacon brothers;502 +atomic opera;503 +spike jones;504 +faith hill;505 +mandy moore;506 +jan werner;507 +kittie;508 +edwin;509 +michael roe;510 +leeland;511 +sammy hagar;512 +frankjavcee;513 +the bangles;514 +joey mcintyre;515 +david rovics;516 +across the border;517 +odd future;518 +bill ward;519 +eddy grant;520 +boa;521 +nirvana;522 +darzamat;523 +ed sheeran;524 +the prodigy;525 +wang chung;526 +balance problems;527 +valient thorr;528 +rupaul;529 +roy clark;530 +ross lynch;531 +ugly kid joe;532 +bettye lavette;533 +harry belafonte;534 +roy buchanan;535 +miguel bosé;536 +greenslade;537 +living legends;538 +bing crosby;539 +adam sandler;540 +the czars;541 +bethany dillon;542 +lea salonga;543 +kmfdm;544 +the diplomats;545 +magneta lane;546 +mira;547 +g herbo;548 +issues;549 +beastie boys;550 +marvin gaye;551 +ashes you leave;552 +mordred;553 +israel houghton;554 +screaming mechanical brain;555 +unknown hinson;556 +jack johnson;557 +do;558 +guns n' roses;559 +october project;560 +adore delano;561 +jedi mind tricks;562 +andrew peterson;563 +millionaires;564 +the beatnuts;565 +gilby clarke;566 +chickenfoot;567 +the stranglers;568 +rev theory;569 +the mccalmans;570 +drowning pool;571 +kutt calhoun;572 +dark fortress;573 +the undertones;574 +kevin gilbert;575 +ffh;576 +seven places;577 +fury in the slaughterhouse;578 +covenant;579 +jason isbell;580 +the creepshow;581 +ashbury heights;582 +shakey graves;583 +brett young;584 +lords of black;585 +the higher;586 +judy garland;587 +boy harsher;588 +status quo;589 +iq;590 +underworld;591 +krizz kaliko;592 +jefferson airplane;593 +billy walker;594 +jackie lomax;595 +lizzy borden;596 +keke wyatt;597 +closterkeller;598 +agnostic front;599 +mary mary;600 +birds in row;601 +mugison;602 +randy travis;603 +glorior belli;604 +amorphis;605 +martika;606 +jason webley;607 +duke ellington;608 +europe;609 +the wilkinsons;610 +a bullet for pretty boy;611 +jodeci;612 +sister hazel;613 +atrocity;614 +little willie john;615 +alexander borodin;616 +belouis some;617 +big boi;618 +newworldson;619 +muddy waters;620 +karen elson;621 +lou bega;622 +ivoryline;623 +pain confessor;624 +dolour;625 +captain beefheart and his magic band;626 +barclay james harvest;627 +todd snider;628 +enslaved;629 +beach fossils;630 +trick daddy;631 +the black dahlia murder;632 +rhapsody of fire;633 +cemetary;634 +patsy cline;635 +figure four;636 +manuel de falla;637 +neil diamond;638 +sworn enemy;639 +elvenking;640 +d.r.a.m.;641 +sonya kitchell;642 +flight of the conchords;643 +eddie from ohio;644 +talk talk;645 +thoushaltnot;646 +this is the kit;647 +crimson glory;648 +the bears;649 +amenra;650 +doris day;651 +death in june;652 +aaron copland;653 +astrud gilberto;654 +luna;655 +fury;656 +corpus christi;657 +soul position;658 +be'lakor;659 +roy orbison;660 +beyond dawn;661 +el-p;662 +watch tower bible and tract society;663 +end of you;664 +falconer;665 +war from a harlots mouth;666 +china;667 +erra;668 +brainpool;669 +psyclon nine;670 +quintorigo;671 +the blind boys of alabama;672 +mr. big;673 +reverend horton heat;674 +yehuda hanani;675 +bell x1;676 +john michael talbot;677 +sigh;678 +james brown;679 +the murder of my sweet;680 +courtney marie andrews;681 +kate alexa;682 +jasmine v;683 +malevolent creation;684 +said the whale;685 +the indelicates;686 +masterplan;687 +every time i die;688 +echosmith;689 +barzin;690 +thelma houston;691 +masters of reality;692 +tony iommi;693 +sex gang children;694 +chaos uk;695 +casper & the cookies;696 +johnny gill;697 +alex harvey;698 +lemar;699 +andre matos;700 +shinee;701 +earl sweatshirt;702 +sanctus real;703 +chilliwack;704 +lionel hampton;705 +faith assembly;706 +dave van ronk;707 +frankie goes to hollywood;708 +badfinger;709 +gazpacho;710 +centro-matic;711 +donald lawrence;712 +me first and the gimme gimmes;713 +margot & the nuclear so and so's;714 +big star;715 +unisonic;716 +the delgados;717 +28 days;718 +veil of maya;719 +tammi terrell;720 +the righteous brothers;721 +david knopfler;722 +ihsahn;723 +high inergy;724 +leaves' eyes;725 +parov stelar;726 +the retrosic;727 +tony rose;728 +tom lehrer;729 +buggles;730 +dennis brown;731 +trashcan sinatras;732 +polarkreis 18;733 +mavis staples;734 +xzibit;735 +black moth super rainbow;736 +yello;737 +the servant;738 +jana mashonee;739 +burl ives;740 +beyond the black;741 +tsjuder;742 +helen o'connell;743 +golden gate quartet;744 +debby boone;745 +beady eye;746 +acid king;747 +westlife;748 +big wreck;749 +manowar;750 +almôra;751 +sarah darling;752 +kenny white;753 +delta spirit;754 +curtis stigers;755 +fun.;756 +feist;757 +karate;758 +sleepy john estes;759 +lamb;760 +the roches;761 +tuatha de danann;762 +horrified;763 +fort minor;764 +jesse harris;765 +berman;766 +shannon & the clams;767 +indigo girls;768 +the matches;769 +eric stewart;770 +jls;771 +kristin hersh;772 +christon gray;773 +loreena mckennitt;774 +charley pride;775 +jocelyn enriquez;776 +helen baylor;777 +hot tuna;778 +skeeter davis;779 +brenton brown;780 +from good homes;781 +leslie hall;782 +natalia kills;783 +chris thompson;784 +circle of dust;785 +transmetal;786 +australian crawl;787 +dying fetus;788 +ratcat;789 +the waifs;790 +elevation worship;791 +bryan ferry;792 +camille;793 +patty griffin;794 +papa charlie jackson;795 +grendel;796 +chris murray;797 +ryan stevenson;798 +kiethevez;799 +the glorious unseen;800 +the ocean blue;801 +conducting from the grave;802 +negativland;803 +del shannon;804 +kathryn scott;805 +this ending;806 +bomfunk mc's;807 +opera ix;808 +steps;809 +the birthday massacre;810 +bronski beat;811 +the burns sisters;812 +willy deville;813 +girlicious;814 +death angel;815 +the quakes;816 +william fitzsimmons;817 +fm;818 +beggars & thieves;819 +richard buckner;820 +iwrestledabearonce;821 +here come the mummies;822 +only crime;823 +saint saviour;824 +millencolin;825 +bigwig;826 +benny mardones;827 +wale;828 +frida;829 +björn ulvaeus & benny andersson;830 +artrosis;831 +neurosis;832 +elis;833 +spain;834 +y&t;835 +jeff lynne;836 +syreeta;837 +ryan adams;838 +the lords of the new church;839 +stephen stills;840 +joel plaskett emergency;841 +blood or whiskey;842 +chenoa;843 +l.t.d.;844 +mariah carey;845 +bauhaus;846 +emma ruth rundle;847 +billy bragg & wilco;848 +sara evans;849 +sara bareilles;850 +cold world;851 +pig destroyer;852 +william elliott whitmore;853 +eyes set to kill;854 +agressor;855 +skiltron;856 +oysterband;857 +versaemerge;858 +now, now;859 +chelsea grin;860 +kaiser/mansfield;861 +george thorogood & the destroyers;862 +foghat;863 +xtc;864 +the nighthawks;865 +eric burdon & war;866 +the cross movement;867 +the winery dogs;868 +edyta górniak;869 +hexrx;870 +the cheeky girls;871 +gazebo;872 +canned heat;873 +anne sophie mutter;874 +sergei prokofiev;875 +beneath the sky;876 +jimmy reed;877 +annihilator;878 +the essex green;879 +john west;880 +bloodhound gang;881 +beth hart & joe bonamassa;882 +lacrimas profundere;883 +jbm;884 +commander cody and his lost planet airmen;885 +smoking popes;886 +seeed;887 +moon martin;888 +terence trent d'arby;889 +the darkest of the hillside thickets;890 +peter tosh;891 +throwdown;892 +the allman brothers band;893 +caribou;894 +axel rudi pell;895 +ne-yo;896 +joe ely;897 +james blake;898 +macklemore & ryan lewis;899 +王力宏 (leehom wang);900 +sam brown;901 +van morrison;902 +bella morte;903 +josé feliciano;904 +john popper;905 +genghis tron;906 +b3;907 +phil keaggy;908 +alesha dixon;909 +peace, love and pitbulls;910 +agents of mercy;911 +elton john;912 +etta james;913 +plus one;914 +spacemen 3;915 +tommy castro;916 +god forbid;917 +abysmal dawn;918 +cadillac blindside;919 +a*teens;920 +q5;921 +mr. president;922 +richmond fontaine;923 +polly paulusma;924 +hear'say;925 +vertical church band;926 +elvis costello;927 +nickelback;928 +the bolshoi;929 +kenny loggins;930 +bad manners;931 +dear reader;932 +tom robinson band;933 +delerium;934 +shirley caesar;935 +trae;936 +tesseract;937 +500 miles to memphis;938 +splitsville;939 +band of susans;940 +edl;941 +half-a-mill;942 +mechanical poet;943 +clay aiken;944 +mars argo;945 +palisades;946 +ian hunter;947 +tracey thorn;948 +jackson heights;949 +downplay;950 +old dominion;951 +jamey johnson;952 +deb talan;953 +little walter;954 +grits;955 +maren ord;956 +longfellow;957 +layzie bone;958 +cuby + blizzards;959 +oszibarack;960 +jillette johnson;961 +the hundred in the hands;962 +culture beat;963 +frozen plasma;964 +paul robeson;965 +alt-j;966 +darkside;967 +other lives;968 +blackfoot;969 +the beta band;970 +sally seltmann;971 +foals;972 +robin williamson;973 +gluecifer;974 +tristan prettyman;975 +guy sebastian;976 +pink guy;977 +johann sebastian bach;978 +methyl ethel;979 +active child;980 +john anderson;981 +neil halstead;982 +phantom planet;983 +john d. loudermilk;984 +greg long;985 +the limeliters;986 +peggy seeger;987 +b la bart k;988 +fallujah;989 +shanice;990 +darius danesh;991 +post malone;992 +audrey;993 +parry gripp;994 +barry white;995 +ravenous;996 +nils lofgren;997 +paddy goes to holyhead;998 +yefim bronfman;999 +prefab sprout;1000 +rose funeral;1001 +the boxmasters;1002 +eluveitie;1003 +tony yayo;1004 +michael learns to rock;1005 +dawes;1006 +lodger;1007 +the joe perry project;1008 +mandragora scream;1009 +kristene dimarco;1010 +today is the day;1011 +riot;1012 +skold;1013 +pendragon;1014 +el debarge;1015 +the wanted;1016 +the pharcyde;1017 +jason derulo;1018 +black light burns;1019 +raintime;1020 +lisa hannigan;1021 +moby;1022 +tedeschi trucks band;1023 +breaking laces;1024 +deströyer 666;1025 +glenn hughes;1026 +martin carthy and dave swarbrick;1027 +the verve;1028 +orleans;1029 +the browns;1030 +the drums;1031 +between the buried and me;1032 +the kingston trio;1033 +jean shepard;1034 +almah;1035 +gare du nord;1036 +the bellamy brothers;1037 +sandra;1038 +the twang;1039 +gorod;1040 +pandora;1041 +mick jagger;1042 +rebellion;1043 +lauren hoffman;1044 +poco;1045 +clara smith;1046 +oscar peterson;1047 +slobberbone;1048 +pitchshifter;1049 +hania;1050 +ziggy marley;1051 +billie jo spears;1052 +dum dum girls;1053 +tricky;1054 +lamont dozier;1055 +slingshot dakota;1056 +koko taylor;1057 +judas priest;1058 +idiot stare;1059 +olivier messiaen;1060 +akala;1061 +it dies today;1062 +fred eaglesmith;1063 +jessie james;1064 +moving mountains;1065 +knights of the abyss;1066 +gregorian;1067 +mr weebl;1068 +johnnie allan;1069 +newton faulkner;1070 +lonely kings;1071 +al stewart;1072 +broods;1073 +zyklon;1074 +basia;1075 +damaged;1076 +the reign of kindo;1077 +black bomb a;1078 +vic damone;1079 +desert rose band;1080 +swing out sister;1081 +arjen anthony lucassen;1082 +kerrs pink;1083 +level 42;1084 +the dollyrots;1085 +giant squid;1086 +jamie cullum;1087 +fritz kalkbrenner;1088 +the whispers;1089 +pilot speed;1090 +adhesive;1091 +leona lewis;1092 +hank williams;1093 +chris botti;1094 +creeper;1095 +tori amos;1096 +evocation;1097 +gothminister;1098 +mandolin orange;1099 +namie amuro;1100 +black sheep;1101 +bleed the sky;1102 +laura pausini;1103 +consequence;1104 +fever ray;1105 +third day;1106 +bed ich smetana;1107 +the chain gang of 1974;1108 +comes with the fall;1109 +duff mckagan's loaded;1110 +israel kamakawiwo'ole;1111 +pixie lott;1112 +bruce dickinson;1113 +sonny landreth;1114 +squeeze;1115 +pennywise;1116 +red café;1117 +the autumn offering;1118 +crashdïet;1119 +neil young;1120 +hi-tek;1121 +hanson;1122 +the blues brothers;1123 +snow tha product;1124 +ibeyi;1125 +carpathian forest;1126 +sheb wooley;1127 +russian red;1128 +american authors;1129 +nick lachey;1130 +jurassic 5;1131 +the smashing pumpkins;1132 +the lyric quartet;1133 +howard shore;1134 +julian lloyd webber;1135 +syleena johnson;1136 +wolf alice;1137 +nico;1138 +beach slang;1139 +robin zander;1140 +tanya tucker;1141 +mac;1142 +mogg/way;1143 +shaggy 2 dope;1144 +godley & creme;1145 +n.e.r.d;1146 +carbon leaf;1147 +august burns red;1148 +1349;1149 +smokey robinson & the miracles;1150 +röyksopp;1151 +stephanie mills;1152 +halestorm;1153 +webb wilder;1154 +chris stapleton;1155 +paul oakenfold;1156 +planetshakers;1157 +andrew belle;1158 +baha men;1159 +memphis willie b.;1160 +andromeda;1161 +cynic;1162 +gil shaham;1163 +george;1164 +toad the wet sprocket;1165 +kiuas;1166 +cat power;1167 +metric;1168 +saving jane;1169 +patrick watson;1170 +faith evans;1171 +trivium;1172 +kelly willis;1173 +my darkest days;1174 +the reason;1175 +david gilmour;1176 +roo panes;1177 +sasha;1178 +sympathy;1179 +go periscope;1180 +american me;1181 +sex pistols;1182 +jay-z;1183 +tiësto;1184 +jean sibelius;1185 +war;1186 +agent 51;1187 +thrice;1188 +amel larrieux;1189 +the futureheads;1190 +arlo guthrie;1191 +the saw doctors;1192 +hungry lucy;1193 +michelle malone;1194 +kay starr;1195 +adestria;1196 +ab-soul;1197 +the merry wives of windsor;1198 +bo carter;1199 +charlotte gainsbourg;1200 +suicidal angels;1201 +zolof the rock & roll destroyer;1202 +brian kennedy;1203 +jess glynne;1204 +the enemy;1205 +crystal lewis;1206 +hopesfall;1207 +helmet;1208 +alicia keys;1209 +tom milsom;1210 +keith green;1211 +macy gray;1212 +libera;1213 +the myriad;1214 +steven wilson;1215 +dennis wilson;1216 +war of ages;1217 +elliott brood;1218 +ace of base;1219 +elefant;1220 +ryker's;1221 +apologetix;1222 +stream of passion;1223 +interface;1224 +susan tedeschi;1225 +circle takes the square;1226 +team starkid;1227 +dillinger four;1228 +jt the bigga figga;1229 +mf doom;1230 +carrie newcomer;1231 +big & rich;1232 +caliban;1233 +project pat;1234 +joan osborne;1235 +juicy j;1236 +beady belle;1237 +victory;1238 +syd barrett;1239 +liv kristine;1240 +anything box;1241 +devin townsend project;1242 +amanda marshall;1243 +die krupps;1244 +sonny boy williamson ii;1245 +assuming we survive;1246 +soko;1247 +much the same;1248 +faunts;1249 +sally oldfield;1250 +the bottle rockets;1251 +kaledon;1252 +lighthouse family;1253 +the mākaha sons;1254 +dark moor;1255 +antagonist a.d.;1256 +lee dorsey;1257 +merle travis;1258 +cursed;1259 +pete rock;1260 +brother cane;1261 +...and oceans;1262 +ancient bards;1263 +the searchers;1264 +cappella;1265 +iced earth;1266 +marmaduke duke;1267 +colin meloy;1268 +venomous concept;1269 +anne murray;1270 +jay farrar;1271 +the town pants;1272 +chubby checker;1273 +tori kelly;1274 +the dodos;1275 +chris spedding;1276 +pmtoday;1277 +thunder lord;1278 +bloodbath;1279 +dear criminals;1280 +aaron carter;1281 +shai hulud;1282 +lil skies;1283 +jeniferever;1284 +jucifer;1285 +the new pornographers;1286 +fabrizio faniello;1287 +fleurie;1288 +mirror of deception;1289 +the real mckenzies;1290 +q-tip;1291 +neuraxis;1292 +rick derringer;1293 +crystal kay;1294 +robert randolph & the family band;1295 +naâman;1296 +little jimmy dickens;1297 +sir mix-a-lot;1298 +krs-one;1299 +daniil trifonov;1300 +morning glory;1301 +cheap trick;1302 +king tee;1303 +angela mccluskey;1304 +derdian;1305 +heitor villa lobos;1306 +nina;1307 +tyrese;1308 +dope stars inc.;1309 +vendetta red;1310 +pussycat;1311 +benjamin gibbard;1312 +nine;1313 +de lux;1314 +william kapell;1315 +vomito negro;1316 +a$ap rocky;1317 +mo b. dick;1318 +gamma ray;1319 +sarah vaughan;1320 +georges bizet;1321 +acid ranch;1322 +deadline;1323 +lady sovereign;1324 +flipsyde;1325 +jim jackson;1326 +violent femmes;1327 +emeli sandé;1328 +la bionda;1329 +sammie;1330 +joe budden;1331 +butterfly boucher;1332 +martha and the muffins;1333 +the faction;1334 +sohn;1335 +the cyrkle;1336 +the butchies;1337 +magna-fi;1338 +jennifer nettles;1339 +udora;1340 +missing persons;1341 +hey mercedes;1342 +cracker;1343 +alphaville;1344 +behexen;1345 +the tremeloes;1346 +the power station;1347 +mark collie;1348 +janet jackson;1349 +out out;1350 +mystery;1351 +warrant;1352 +kamelot;1353 +max webster;1354 +kristian stanfill;1355 +ken hensley;1356 +lyfe jennings;1357 +gusgus;1358 +after the burial;1359 +sam tsui;1360 +tony orlando & dawn;1361 +guy clark;1362 +electric wizard;1363 +vanna;1364 +nicole c. mullen;1365 +prozak;1366 +spahn ranch;1367 +william mcdowell;1368 +brandy clark;1369 +jamie lidell;1370 +grief;1371 +the maccabees;1372 +weedeater;1373 +marlango;1374 +hirax;1375 +elvis presley;1376 +aly & aj;1377 +ellis paul;1378 +we the kings;1379 +bound stems;1380 +symphony x;1381 +randy stonehill;1382 +man;1383 +centinex;1384 +blaine larsen;1385 +aqueduct;1386 +june of 44;1387 +we came as romans;1388 +natasha bedingfield;1389 +divinefire;1390 +alan hull;1391 +outlawz;1392 +seasick steve;1393 +nerina pallot;1394 +sandy denny;1395 +glenn gould;1396 +matt dusk;1397 +strawberry alarm clock;1398 +stryper;1399 +stefanie heinzmann;1400 +miracle of sound;1401 +pop unknown;1402 +rahsaan patterson;1403 +yellowman;1404 +the clay people;1405 +the good life;1406 +leroy carr;1407 +sonata arctica;1408 +tom odell;1409 +that handsome devil;1410 +birdy;1411 +jimmy cliff;1412 +kompressor;1413 +deadmau5;1414 +linda ronstadt;1415 +ufx;1416 +blind blake;1417 +jody watley;1418 +razed in black;1419 +dave clark five;1420 +diddy;1421 +anacrusis;1422 +dropkick murphys;1423 +doyle bramhall;1424 +lisa "left eye" lopes;1425 +ll cool j;1426 +deadsoul tribe;1427 +sunset rubdown;1428 +heaven 17;1429 +pavlov's dog;1430 +billie eilish;1431 +dido;1432 +deathboy;1433 +antaeus;1434 +dreamland;1435 +the beloved;1436 +the arrogant worms;1437 +closet monster;1438 +eartha kitt;1439 +radu lupu;1440 +cinderella effect;1441 +anathema;1442 +for the fallen dreams;1443 +shola ama;1444 +big thief;1445 +armand van helden;1446 +fake?;1447 +phil harris;1448 +loggins & messina;1449 +promise of redemption;1450 +the walkabouts;1451 +eisley;1452 +big joe turner;1453 +axenstar;1454 +hank williams iii;1455 +b.o.b.;1456 +wallis bird;1457 +as i lay dying;1458 +trey songz;1459 +charlotte hatherley;1460 +nneka;1461 +anúna;1462 +asia;1463 +mcauley schenker group;1464 +rose polenzani;1465 +john mayer;1466 +grant-lee phillips;1467 +taj mahal;1468 +ruston kelly;1469 +melissa manchester;1470 +lenka;1471 +kira isabella;1472 +hap palmer;1473 +taken by trees;1474 +anni b sweet;1475 +planet p project;1476 +the velvet underground;1477 +hoagy carmichael;1478 +testament;1479 +the 3rd and the mortal;1480 +fever tree;1481 +iris dement;1482 +happy days;1483 +prostitute disfigurement;1484 +the andrews sisters;1485 +eyedea & abilities;1486 +mipso;1487 +dinu lipatti;1488 +josephine foster;1489 +stephen sondheim;1490 +little big;1491 +kip winger;1492 +the voidz;1493 +matchbook romance;1494 +green carnation;1495 +xiu xiu;1496 +the hard-ons;1497 +glasseater;1498 +bloodlined calligraphy;1499 +yodelice;1500 +infectious grooves;1501 +alex lloyd;1502 +overcome;1503 +tom dice;1504 +rorschach test;1505 +nat & alex wolff;1506 +van halen;1507 +robert earl keen;1508 +dave hollister;1509 +rob thomas;1510 +chanté moore;1511 +lyle lovett;1512 +aaron lines;1513 +my life with the thrill kill kult;1514 +honne;1515 +the flatliners;1516 +eric b. & rakim;1517 +old man gloom;1518 +new found glory;1519 +louis logic;1520 +murray perahia;1521 +bass drum of death;1522 +702;1523 +jamie o'neal;1524 +the sheila divine;1525 +chris ledoux;1526 +huski;1527 +wolf parade;1528 +emmure;1529 +defiance, ohio;1530 +nine below zero;1531 +jamie winchester;1532 +cece winans;1533 +splashdown;1534 +the strumbellas;1535 +otis spann;1536 +juice wrld;1537 +brett anderson;1538 +the ambassador;1539 +arturo benedetti michelangeli;1540 +spinal tap;1541 +wild strawberries;1542 +mystikal;1543 +acumen nation;1544 +the ex;1545 +pearls before swine;1546 +the ink spots;1547 +mayhem;1548 +e;1549 +sara noxx;1550 +kid cudi;1551 +neko case;1552 +dethklok;1553 +vast;1554 +lila mccann;1555 +boxcar willie;1556 +the soundtrack of our lives;1557 +the deep dark woods;1558 +johnossi;1559 +sinéad lohan;1560 +tragic black;1561 +public enemy;1562 +toby keith;1563 +jesus on extasy;1564 +after forever;1565 +lightnin' hopkins;1566 +any given day;1567 +terminal choice;1568 +head east;1569 +sturgill simpson;1570 +cavalera conspiracy;1571 +pitboss 2000;1572 +broken social scene;1573 +hanzel und gretyl;1574 +kajagoogoo;1575 +village people;1576 +the most serene republic;1577 +ernest tubb and loretta lynn;1578 +arno;1579 +ninja sex party;1580 +bts;1581 +charlie simpson;1582 +criss angel;1583 +local natives;1584 +elliphant;1585 +right away, great captain!;1586 +frankie valli;1587 +dion;1588 +j. tillman;1589 +krayzie bone;1590 +atlanta rhythm section;1591 +grimes;1592 +slapp happy;1593 +voivod;1594 +ella fitzgerald;1595 +maddy prior;1596 +exo;1597 +bobby v;1598 +cherry glazerr;1599 +jackie deshannon;1600 +nancy sinatra;1601 +dragonheart;1602 +the casualties;1603 +polysics;1604 +cliff richard;1605 +sleeping with sirens;1606 +dew-scented;1607 +diva destruction;1608 +jens lekman;1609 +charlie landsborough;1610 +born ruffians;1611 +joe diffie;1612 +sonny terry;1613 +the black angels;1614 +envy;1615 +mary lou lord;1616 +of mice & men;1617 +tina arena;1618 +candlemass;1619 +stacie orrico;1620 +too $hort;1621 +bombay bicycle club;1622 +the dc3;1623 +marié digby;1624 +frank ocean;1625 +slash's snakepit;1626 +akcent;1627 +mortal sin;1628 +the rural alberta advantage;1629 +alter bridge;1630 +caligula's horse;1631 +diana ross;1632 +strand of oaks;1633 +austrian death machine;1634 +ana popovic;1635 +skepticism;1636 +shirley horn;1637 +siva six;1638 +valentine wolfe;1639 +titanic sinclair;1640 +joshua perahia;1641 +gallows;1642 +luxt;1643 +nick lowe;1644 +clarence "gatemouth" brown;1645 +sweet noise;1646 +thank you scientist;1647 +cherish the ladies;1648 +ten years after;1649 +frost;1650 +first blood;1651 +nightwish;1652 +musiq soulchild;1653 +big bill broonzy;1654 +benjamin francis leftwich;1655 +phantom blue;1656 +dune;1657 +hangnail;1658 +harold melvin & the blue notes;1659 +big d and the kids table;1660 +zeromancer;1661 +jello biafra;1662 +yg;1663 +katharine mcphee;1664 +quinn xcii;1665 +mississippi john hurt;1666 +new trolls;1667 +wizards;1668 +kix;1669 +slapshot;1670 +tor miller;1671 +xentrifuge;1672 +toni braxton;1673 +finch;1674 +caroline herring;1675 +dreadful shadows;1676 +ringworm;1677 +cory asbury;1678 +dezperadoz;1679 +mac davis;1680 +dionysus;1681 +michael w. smith;1682 +cold as life;1683 +peabo bryson;1684 +k.d. lang;1685 +grammatrain;1686 +jorn;1687 +no-man;1688 +nocturne;1689 +the screaming jets;1690 +charli xcx;1691 +tactical sekt;1692 +oomph!;1693 +atlas sound;1694 +the idle race;1695 +helstar;1696 +toxik;1697 +jesus culture;1698 +cissy houston;1699 +catman cohen;1700 +strike anywhere;1701 +toni childs;1702 +mika;1703 +theory in practice;1704 +lucinda williams;1705 +lord belial;1706 +raul midón;1707 +ida;1708 +trisha yearwood;1709 +bad astronaut;1710 +the runaways;1711 +a day to remember;1712 +milk inc.;1713 +fisher;1714 +king kobra;1715 +ma rainey;1716 +ralph stanley;1717 +andr watts;1718 +gregory and the hawk;1719 +the temptations;1720 +flaw;1721 +terror squad;1722 +black;1723 +bolt thrower;1724 +matt goss;1725 +nappy roots;1726 +a$ap ferg;1727 +shawn mendes;1728 +alison krauss & union station;1729 +eric johnson;1730 +ashley monroe;1731 +old crow medicine show;1732 +kelis;1733 +bad habit;1734 +van canto;1735 +the birthday party;1736 +rowland s. howard;1737 +marsha ambrosius;1738 +little dragon;1739 +k'jon;1740 +jack white;1741 +cactus;1742 +daft punk;1743 +jon oliva's pain;1744 +a$ap mob;1745 +emika;1746 +lazar berman;1747 +mark kozelek;1748 +ice-t;1749 +little richard;1750 +elijah blake;1751 +the laurie berkner band;1752 +clara luzia;1753 +ma$e;1754 +dikembe;1755 +boz scaggs;1756 +antony and the johnsons;1757 +autopilot off;1758 +big audio dynamite;1759 +grant lee buffalo;1760 +john reuben;1761 +mission of burma;1762 +unloco;1763 +transit;1764 +marina and the diamonds;1765 +alela diane;1766 +the sorrow;1767 +gossip;1768 +emerald;1769 +lucille bogan;1770 +frank zappa;1771 +the coathangers;1772 +captain jack;1773 +stellastarr*;1774 +david kersh;1775 +broken bones;1776 +hayley kiyoko;1777 +wire;1778 +thurston moore;1779 +cop shoot cop;1780 +the white buffalo;1781 +bad books;1782 +irene cara;1783 +gorillaz;1784 +the gap band;1785 +lead belly;1786 +cassadee pope;1787 +elvis depressedly;1788 +curtis mayfield;1789 +waylon;1790 +the gun club;1791 +behemoth;1792 +she wants revenge;1793 +the crüxshadows;1794 +týr;1795 +dan fogelberg;1796 +stan ridgway;1797 +blind witness;1798 +deerhunter;1799 +agalloch;1800 +grand puba;1801 +heavens edge;1802 +the acacia strain;1803 +beseech;1804 +sting;1805 +rival sons;1806 +henry jamison;1807 +the black lillies;1808 +the cog is dead;1809 +benno moiseiwitsch;1810 +nazz;1811 +greg brown;1812 +reel big fish;1813 +the muppets;1814 +threshold;1815 +tracie spencer;1816 +cimorelli;1817 +alexandra burke;1818 +whigfield;1819 +eminem;1820 +wolverine;1821 +grave maker;1822 +example;1823 +lambchop;1824 +madeleine peyroux;1825 +bondage fairies;1826 +darren hanlon;1827 +lyria;1828 +capital kings;1829 +john pizzarelli;1830 +high on fire;1831 +stereolab;1832 +machines of loving grace;1833 +kim carnes;1834 +so many dynamos;1835 +phony ppl;1836 +san cisco;1837 +emilie autumn;1838 +pietro locatelli;1839 +solefald;1840 +kellie pickler;1841 +the maranatha! singers;1842 +danbert nobacon;1843 +soulja boy;1844 +mario winans;1845 +camille saint sa ns;1846 +indecision;1847 +lasgo;1848 +karyn white;1849 +hurts;1850 +between the trees;1851 +nat king cole;1852 +front 242;1853 +johannes brahms;1854 +the national;1855 +shane barnard;1856 +chris knox;1857 +poison girls;1858 +oh, sleeper;1859 +hell is for heroes;1860 +pfr;1861 +john lee hooker;1862 +gramatik;1863 +moya brennan;1864 +pop evil;1865 +scar symmetry;1866 +silly wizard;1867 +the ventures;1868 +steve holy;1869 +devotchkas;1870 +ignite;1871 +wayne newton;1872 +the gufs;1873 +decapitated;1874 +billie the vision & the dancers;1875 +thestart;1876 +idle cure;1877 +jill sobule;1878 +the soviettes;1879 +the irish rovers;1880 +münchener freiheit;1881 +pentagram;1882 +masterboy;1883 +return;1884 +minus story;1885 +satan;1886 +byron cage;1887 +listener;1888 +the mars volta;1889 +jennifer love hewitt;1890 +eartha;1891 +no doctors;1892 +steve hackett;1893 +elvin bishop;1894 +k'naan;1895 +ruby;1896 +princess nokia;1897 +ellie goulding;1898 +material issue;1899 +fun boy three;1900 +circulatory system;1901 +the road hammers;1902 +brian mcknight;1903 +"weird al" yankovic;1904 +the wailers;1905 +kurupt;1906 +criminal;1907 +bal-sagoth;1908 +lou reed;1909 +queen;1910 +rudimentary peni;1911 +a great big world;1912 +jarboe;1913 +augie march;1914 +jim guthrie;1915 +emma bunton;1916 +aaron watson;1917 +έλενα παπαρίζου;1918 +blue cheer;1919 +mark harris;1920 +alexander scriabin;1921 +andrew gold;1922 +climax blues band;1923 +conjure one;1924 +blind guardian;1925 +stephen schwartz;1926 +martha wainwright;1927 +lil' flip;1928 +katherine jenkins;1929 +amy shark;1930 +styles p;1931 +new model army;1932 +franz liszt;1933 +ben weasel;1934 +john k. samson;1935 +jason anderson;1936 +sheena easton;1937 +inna;1938 +mayer hawthorne;1939 +easy rider;1940 +eddy arnold;1941 +zoegirl;1942 +jimmy barnes;1943 +tear da club up thugs;1944 +daughter;1945 +buzzcocks;1946 +freezepop;1947 +steve aoki;1948 +kierra sheard;1949 +captain beyond;1950 +sabrina claudio;1951 +mc shan;1952 +the j. geils band;1953 +camel;1954 +indica;1955 +attack in black;1956 +the jam;1957 +bananarama;1958 +al jarreau;1959 +eric carmen;1960 +gwar;1961 +us the duo;1962 +ziggy alberts;1963 +amir obè;1964 +25 ta life;1965 +newsboys;1966 +chris knight;1967 +marlene dietrich;1968 +112;1969 +wonderwall;1970 +officer negative;1971 +enochian crescent;1972 +jupiter one;1973 +whitecross;1974 +tim mcgraw;1975 +bile;1976 +brandi carlile;1977 +danzig;1978 +twiztid;1979 +david baerwald;1980 +jimmy webb;1981 +mamas gun;1982 +harry chapin;1983 +holy ghost!;1984 +stephen hough;1985 +k.t. oslin;1986 +robin trower;1987 +us3;1988 +esben and the witch;1989 +schiller;1990 +god lives underwater;1991 +hayseed dixie;1992 +polluted inheritance;1993 +nicki minaj;1994 +robin gibb;1995 +pinback;1996 +bobbie gentry;1997 +freakwater;1998 +kite;1999 +kid down;2000 +georges cziffra;2001 +sivert høyem;2002 +conor oberst;2003 +i'm from barcelona;2004 +shining;2005 +henry purcell;2006 +jeremy messersmith;2007 +goat of mendes;2008 +catch 22;2009 +vampire rodents;2010 +the go-go's;2011 +noah gundersen;2012 +diablo swing orchestra;2013 +uncle dave macon;2014 +john eddie;2015 +calvin harris;2016 +roomful of blues;2017 +bane;2018 +sam lewis;2019 +alejandro escovedo;2020 +kekal;2021 +manticora;2022 +frankie lymon & the teenagers;2023 +randy meisner;2024 +carcass;2025 +nile;2026 +circus maximus;2027 +non phixion;2028 +eric woolfson;2029 +starship;2030 +kaiser chiefs;2031 +sexy sadie;2032 +confide;2033 +boy meets girl;2034 +henryk szeryng;2035 +wynter gordon;2036 +jay-jay johanson;2037 +hannah fury;2038 +mike jones;2039 +bebe & cece winans;2040 +trip lee;2041 +tigers jaw;2042 +hector berlioz;2043 +minus the bear;2044 +johnny winter;2045 +my sister's machine;2046 +gilbert o'sullivan;2047 +jean michel jarre;2048 +jody miller;2049 +skylark;2050 +the poodles;2051 +fear of domination;2052 +the donefors;2053 +zed yago;2054 +martha argerich;2055 +faun fables;2056 +joy electric;2057 +the grass roots;2058 +cygnosic;2059 +disfear;2060 +crosby, stills, nash & young;2061 +69 boyz;2062 +celesty;2063 +the forecast;2064 +the magnetic fields;2065 +miranda lambert;2066 +veto;2067 +the offspring;2068 +bobby goldsboro;2069 +calibretto;2070 +common rider;2071 +10cc;2072 +tim hughes;2073 +bald vulture;2074 +david cassidy;2075 +simple minds;2076 +little man tate;2077 +carla thomas;2078 +cher lloyd;2079 +cameo;2080 +tko;2081 +george frideric handel;2082 +immaculate fools;2083 +kero kero bonito;2084 +john sebastian;2085 +joe nichols;2086 +classified;2087 +velvet revolver;2088 +skip the use;2089 +ratt;2090 +gilberto gil;2091 +the miracles;2092 +the subways;2093 +screwed up click;2094 +fm static;2095 +further seems forever;2096 +barry louis polisar;2097 +antiskeptic;2098 +den harrow;2099 +eleni mandell;2100 +mungo jerry;2101 +fucked up;2102 +jermaine jackson;2103 +freedom call;2104 +phillip phillips;2105 +van der graaf generator;2106 +h-town;2107 +madvillain;2108 +pietasters;2109 +sonicflood;2110 +thomas dolby;2111 +scud mountain boys;2112 +orphanage;2113 +eleventyseven;2114 +peter hammill;2115 +kaysha;2116 +skyharbor;2117 +south border;2118 +mad marge and the stonecutters;2119 +ben kweller;2120 +monstrosity;2121 +young galaxy;2122 +pusha t;2123 +john wesley;2124 +glass harp;2125 +blue system;2126 +pain of salvation;2127 +film school;2128 +plasmatics;2129 +down by law;2130 +circus of power;2131 +left alone;2132 +girls under glass;2133 +saga;2134 +redemption;2135 +memphis may fire;2136 +aion;2137 +kj-52;2138 +gaia epicus;2139 +stacy lattisaw;2140 +larry norman;2141 +david lee roth;2142 +willie nelson;2143 +melody gardot;2144 +in the midst of lions;2145 +iron butterfly;2146 +katy rose;2147 +izz;2148 +sevyn streeter;2149 +pendulum;2150 +cult of luna;2151 +avalanche city;2152 +brother firetribe;2153 +lena;2154 +steve vai;2155 +motosierra;2156 +the bouncing souls;2157 +maher zain;2158 +colbie caillat;2159 +blaze ya dead homie;2160 +kyung wha chung;2161 +delta goodrem;2162 +lena katina;2163 +the veronicas;2164 +asleep at the wheel;2165 +anne clark;2166 +jimmie vaughan;2167 +wildpath;2168 +autumnblaze;2169 +lefty frizzell;2170 +the weakerthans;2171 +real estate;2172 +dj drama;2173 +joji;2174 +little milton;2175 +beholder;2176 +grace jones;2177 +wolfheart;2178 +kt tunstall;2179 +robert forster;2180 +lana lane;2181 +meat loaf;2182 +mark chesnutt;2183 +autumn;2184 +bronze nazareth;2185 +ladysmith black mambazo;2186 +memphis minnie;2187 +the plimsouls;2188 +36 crazyfists;2189 +private line;2190 +nikolai medtner;2191 +jaden smith;2192 +chris cagle;2193 +beatnik termites;2194 +bernard butler;2195 +emin;2196 +major accident;2197 +the mayan factor;2198 +stonewall jackson;2199 +rat boy;2200 +das efx;2201 +roxette;2202 +tears for fears;2203 +hank locklin;2204 +n.w.a;2205 +hadouken!;2206 +king diamond;2207 +axe;2208 +lolo;2209 +rufus thomas;2210 +montgomery gentry;2211 +the front bottoms;2212 +gabrielle;2213 +beng beng cocktail;2214 +wyclef jean;2215 +cœur de pirate;2216 +faithless;2217 +heavy heavy low low;2218 +cutting crew;2219 +limbeck;2220 +saukrates;2221 +artie shaw;2222 +jojo;2223 +red rider;2224 +nikolai rimsky korsakov;2225 +choking victim;2226 +the scene aesthetic;2227 +fight amp;2228 +émilie simon;2229 +christoph willibald gluck;2230 +boney m.;2231 +ookla the mok;2232 +beck;2233 +mcfly;2234 +hey ocean!;2235 +dixie chicks;2236 +lindsay lohan;2237 +from autumn to ashes;2238 +giovanni battista pergolesi;2239 +boondox;2240 +wilhelm kempff;2241 +jay & the americans;2242 +the game;2243 +night in gales;2244 +blazin' squad;2245 +lords of acid;2246 +darlingside;2247 +squealer;2248 +the ghost inside;2249 +abbey lincoln;2250 +cake bake betty;2251 +all that remains;2252 +bunny wailer;2253 +culture club;2254 +jim croce;2255 +vixen;2256 +chelsea wolfe;2257 +the zutons;2258 +the ship;2259 +timbuk3;2260 +wise guys;2261 +gabriel faur ;2262 +prototype;2263 +great big sea;2264 +celtic frost;2265 +stage dolls;2266 +vinnie paz;2267 +symbols;2268 +casanova;2269 +horse the band;2270 +raul seixas;2271 +phil collins;2272 +belphegor;2273 +a whisper in the noise;2274 +rufio;2275 +trin-i-tee 5;2276 +isaac hayes;2277 +i am ghost;2278 +gregg allman;2279 +three 6 mafia;2280 +t. mills;2281 +as cities burn;2282 +fear factory;2283 +good riddance;2284 +daniel m ller schott;2285 +stromkern;2286 +spirogyra;2287 +resurrection band;2288 +jamie's elsewhere;2289 +one bad pig;2290 +renaldo & the loaf;2291 +danny kaye;2292 +belle and sebastian;2293 +cryptopsy;2294 +yeah yeah yeahs;2295 +the jayhawks;2296 +mel tillis;2297 +yazoo;2298 +colin hay;2299 +the desert sessions;2300 +the dismemberment plan;2301 +sammy adams;2302 +discipline;2303 +secrets of the moon;2304 +tapping the vein;2305 +army of the pharaohs;2306 +big bad voodoo daddy;2307 +professor green;2308 +roine stolt;2309 +wu-tang clan;2310 +tracy byrd;2311 +big maybelle;2312 +aage kvalbein;2313 +club nouveau;2314 +mose allison;2315 +edenbridge;2316 +the foundations;2317 +darkseed;2318 +dear and the headlights;2319 +twila paris;2320 +ed bruce;2321 +damien dempsey;2322 +starlight mints;2323 +accessory;2324 +ador dorath;2325 +boogie down productions;2326 +stars;2327 +creedence clearwater revival;2328 +dwight yoakam;2329 +4him;2330 +gorguts;2331 +demons & wizards;2332 +陰陽座;2333 +barstool prophets;2334 +paolo nutini;2335 +asking alexandria;2336 +kid rock;2337 +jerusalem;2338 +them;2339 +robert wyatt;2340 +the weeknd;2341 +jeff deyo;2342 +beartooth;2343 +pilot;2344 +jenny hval;2345 +the devil wears prada;2346 +karine polwart;2347 +maxwell;2348 +michael rabin;2349 +babyface;2350 +white lies;2351 +groundation;2352 +nina hagen;2353 +tracy lawrence;2354 +ring of fire;2355 +koda kumi;2356 +umphrey's mcgee;2357 +polkadot cadaver;2358 +alabama;2359 +edge of sanity;2360 +thyrane;2361 +dick brave & the backbeats;2362 +pantera;2363 +françoise hardy;2364 +whirlwind heat;2365 +lightning seeds;2366 +disrupt;2367 +true colors;2368 +vérité;2369 +jeremy riddle;2370 +billy crawford;2371 +royal hunt;2372 +apache indian;2373 +peggy lee;2374 +the flight of sleipnir;2375 +hard-fi;2376 +ladytron;2377 +massacration;2378 +john browning;2379 +grant hart;2380 +chris hillman;2381 +bear vs. shark;2382 +descendents;2383 +mark ronson;2384 +nofx;2385 +rich kids on lsd;2386 +jordin sparks;2387 +vv brown;2388 +michael franks;2389 +aram khachaturian;2390 +bathory;2391 +jessica pratt;2392 +mormon tabernacle choir;2393 +dan hill;2394 +laleh;2395 +curl up and die;2396 +jonah matranga;2397 +anna tsuchiya;2398 +jack howard;2399 +nick heyward;2400 +steven curtis chapman;2401 +pimp c;2402 +chef'special;2403 +super junior-d&e;2404 +willie nelson & wynton marsalis;2405 +lionel richie;2406 +martyr;2407 +eagles;2408 +project pitchfork;2409 +crosby, stills & nash;2410 +slim thug;2411 +frankie j;2412 +the stereo;2413 +blues pills;2414 +fog;2415 +bow wow wow;2416 +gowan;2417 +king charles;2418 +sviatoslav richter;2419 +m. ward;2420 +freshlyground;2421 +ed schrader's music beat;2422 +company flow;2423 +painbastard;2424 +buddy jewell;2425 +mckinney's cotton pickers;2426 +mandisa;2427 +watershed;2428 +the wailin' jennys;2429 +faderhead;2430 +mötley crüe;2431 +stormwarrior;2432 +keb' mo';2433 +jimmy witherspoon;2434 +the lucksmiths;2435 +faster pussycat;2436 +knightowl;2437 +keri hilson;2438 +mxpx;2439 +the nice;2440 +ritual;2441 +oxymoron;2442 +catamenia;2443 +vince gill;2444 +bill fay;2445 +toy-box;2446 +love unlimited;2447 +mc frontalot;2448 +dolly parton;2449 +papoose;2450 +demi lovato;2451 +rhodes;2452 +big joe williams;2453 +charlie rich;2454 +extreme noise terror;2455 +wilco;2456 +low roar;2457 +carrie underwood;2458 +when particles collide;2459 +3 feet smaller;2460 +the supremes & the four tops;2461 +the police;2462 +empress of;2463 +herman brood;2464 +be your own pet;2465 +kill switch...klick;2466 +superjoint ritual;2467 +lynyrd skynyrd;2468 +al green;2469 +hilltop hoods;2470 +ghostlimb;2471 +chamber - l'orchestre de chambre noir;2472 +thou;2473 +the icicle works;2474 +debbie harry;2475 +victoria beckham;2476 +clare maguire;2477 +cause & effect;2478 +marion;2479 +the lawrence arms;2480 +x;2481 +the russian futurists;2482 +maggie rose;2483 +jim cuddy;2484 +the turtles;2485 +as blood runs black;2486 +the night flight orchestra;2487 +graziano romani;2488 +alcatrazz;2489 +lp;2490 +jon foreman;2491 +popa chubby;2492 +alfred cortot;2493 +eddi reader;2494 +plushgun;2495 +sugababes;2496 +sesame street;2497 +johnny cash;2498 +joe walsh;2499 +jeanette biedermann;2500 +ashford & simpson;2501 +sleep;2502 +hum;2503 +papas fritas;2504 +fifteen;2505 +denzel curry;2506 +phedora;2507 +anders osborne;2508 +the morning of;2509 +cash rivers and the sinners;2510 +blueprint;2511 +slim dusty;2512 +acappella;2513 +katatonia;2514 +diary of dreams;2515 +deine lakaien;2516 +rick wakeman;2517 +freedom fry;2518 +fruupp;2519 +jean baptiste lully;2520 +october 31;2521 +sinister;2522 +jesse mccartney;2523 +vigilantes of love;2524 +elegant machinery;2525 +corbin bleu;2526 +gza/genius;2527 +alison wonderland;2528 +kelly price;2529 +destruction;2530 +fractured;2531 +david ford;2532 +julie miller;2533 +joe mcelderry;2534 +phinehas;2535 +sylvan esso;2536 +basement jaxx;2537 +shearwater;2538 +deadstar assembly;2539 +wildbirds & peacedrums;2540 +patty smyth;2541 +short stack;2542 +jupiter apple;2543 +raven-symoné;2544 +misery loves co.;2545 +the motels;2546 +steppenwolf;2547 +vic chesnutt;2548 +asha;2549 +the almighty;2550 +lauryn hill;2551 +khalid;2552 +great lake swimmers;2553 +ashanti;2554 +蔡依林 (jolin tsai);2555 +donnie munro;2556 +john fogerty;2557 +kimberley locke;2558 +keith moon;2559 +janis joplin;2560 +reamonn;2561 +psychopathic rydas;2562 +air supply;2563 +ashlee simpson;2564 +tame impala;2565 +perzonal war;2566 +adem;2567 +franz ferdinand;2568 +martina mcbride;2569 +natalie cole;2570 +jason falkner;2571 +rosalyn tureck;2572 +missy higgins;2573 +beach house;2574 +current 93;2575 +a hill to die upon;2576 +ghoti hook;2577 +forgive durden;2578 +gojira;2579 +jay ferguson;2580 +eilera;2581 +kate nash;2582 +foxes;2583 +at the drive-in;2584 +job for a cowboy;2585 +from ashes to new;2586 +brooke white;2587 +dwele;2588 +vacuum;2589 +samson fran ois;2590 +loverboy;2591 +black country communion;2592 +paul revere and the raiders;2593 +chris brown;2594 +tommy lee;2595 +vengaboys;2596 +joy zipper;2597 +bella hardy;2598 +blondie;2599 +brian setzer;2600 +mc zulu;2601 +building 429;2602 +cindy bullens;2603 +cyne;2604 +b*witched;2605 +the black eyed peas;2606 +paul weller;2607 +gun;2608 +illogic;2609 +men at work;2610 +luv';2611 +shadows fall;2612 +the crest;2613 +zendaya;2614 +runemagick;2615 +john farnham;2616 +josh ritter;2617 +funeral;2618 +wanda jackson;2619 +waylon jennings;2620 +falco;2621 +marlon williams;2622 +seals & crofts;2623 +kurt elling;2624 +neon hitch;2625 +the swift;2626 +sub focus;2627 +bent knee;2628 +trevor rabin;2629 +bazzi;2630 +jim's big ego;2631 +andrew huang;2632 +glenn miller;2633 +donna summer;2634 +the meteors;2635 +ugly duckling;2636 +李玟 (coco lee);2637 +bruno mars;2638 +sambassadeur;2639 +the neville brothers;2640 +terrorgruppe;2641 +the lone bellow;2642 +deer tick;2643 +bentley jones;2644 +carter the unstoppable sex machine;2645 +connie talbot;2646 +adult.;2647 +crosby & nash;2648 +ayọ;2649 +jay rock;2650 +crystal castles;2651 +tyrone wells;2652 +heavens to betsy;2653 +the limousines;2654 +chris garneau;2655 +13th floor elevators;2656 +dirty pretty things;2657 +the more i see;2658 +raimon;2659 +winterstorm;2660 +spice 1;2661 +jade valerie;2662 +kacey musgraves;2663 +roko;2664 +lights of euphoria;2665 +the bronx;2666 +raffaella carrà;2667 +mastercastle;2668 +city and colour;2669 +salvador;2670 +carolyn arends;2671 +motörhead;2672 +justin young;2673 +the dreadnoughts;2674 +india.arie;2675 +decoded feedback;2676 +guy verlinde;2677 +the clientele;2678 +rapture;2679 +caterina valente;2680 +battle beast;2681 +wednesday 13;2682 +walter gieseking;2683 +the duckworth lewis method;2684 +bloc party;2685 +zuill bailey;2686 +mother love bone;2687 +martha and the vandellas;2688 +blitzkid;2689 +nightrage;2690 +martin zellar;2691 +38 special;2692 +christina grimmie;2693 +dagoba;2694 +glenn tipton;2695 +blue rodeo;2696 +acoustic junction;2697 +led zeppelin;2698 +evergrey;2699 +the locust;2700 +jazmine sullivan;2701 +the colourfield;2702 +yob;2703 +vengeance rising;2704 +chunk! no, captain chunk!;2705 +the alan parsons project;2706 +dustin kensrue;2707 +fool's garden;2708 +saucy monky;2709 +sergei rachmaninoff;2710 +charlie sexton;2711 +babyshambles;2712 +nina simone;2713 +born against;2714 +dååth;2715 +jon allen;2716 +leigh nash;2717 +the vandals;2718 +matt redman;2719 +marian hill;2720 +tanita tikaram;2721 +leonard bernstein;2722 +raffi;2723 +pharao;2724 +miseration;2725 +allan taylor;2726 +rita ora;2727 +gary glitter;2728 +girlschool;2729 +k-ci & jojo;2730 +jimmy dorsey;2731 +.moneen.;2732 +imperia;2733 +virtuoso;2734 +votum;2735 +lucy woodward;2736 +alvin stardust;2737 +will young;2738 +crown of thorns;2739 +arcadi volodos;2740 +the jim yoshii pile-up;2741 +a life divided;2742 +children 18;2743 +james ingram;2744 +梶浦由記 (yuki kajiura);2745 +ynw melly;2746 +jump, little children;2747 +trans-siberian orchestra;2748 +armageddon;2749 +faces;2750 +bokka;2751 +leviathan;2752 +the black keys;2753 +the panic division;2754 +roy drusky;2755 +veggietales;2756 +jt music;2757 +tim o'brien;2758 +brockhampton;2759 +the sundays;2760 +hayes carll;2761 +leatherface;2762 +spirit of the west;2763 +dawn landes;2764 +kygo;2765 +isis;2766 +meek mill;2767 +brisa roché;2768 +freesscape;2769 +joe hill;2770 +pride and fall;2771 +54-40;2772 +washed out;2773 +michael sembello;2774 +crowded house;2775 +cpr;2776 +steve winwood;2777 +jukebox the ghost;2778 +atari teenage riot;2779 +ballyhoo!;2780 +eddie floyd;2781 +trophy scars;2782 +erykah badu;2783 +james cotton;2784 +kristinia debarge;2785 +morbid angel;2786 +code red;2787 +al kooper;2788 +monty python;2789 +the mary onettes;2790 +future;2791 +shabazz the disciple;2792 +sad café;2793 +x-fusion;2794 +deniece williams;2795 +robert gordon;2796 +seabear;2797 +wallows;2798 +john illsley;2799 +dream theater;2800 +secret lives of the freemasons;2801 +josef suk;2802 +the bled;2803 +gregor piatigorsky;2804 +john ralston;2805 +tim kasher;2806 +the hellacopters;2807 +autopsy;2808 +the silencers;2809 +hank green;2810 +abk;2811 +hound dog taylor;2812 +angela bofill;2813 +wade bowen;2814 +jamestown story;2815 +andy partridge;2816 +echolyn;2817 +search the city;2818 +giacomo puccini;2819 +gregory isaacs;2820 +stormtroopers of death;2821 +silkk the shocker;2822 +1208;2823 +everlife;2824 +bobby mcferrin;2825 +pretty ricky;2826 +ronna reeves;2827 +annie lennox;2828 +london grammar;2829 +john doe;2830 +shel silverstein;2831 +blue october;2832 +aaron lee tasjan;2833 +marion raven;2834 +carl perkins;2835 +big pokey;2836 +eddie cochran;2837 +enter the haggis;2838 +burden of a day;2839 +tourniquet;2840 +emilíana torrini;2841 +brian doerksen;2842 +crossfaith;2843 +ludwig van beethoven;2844 +good clean fun;2845 +an horse;2846 +kali uchis;2847 +stone breath;2848 +daniele liverani;2849 +patrick stump;2850 +henry krieger;2851 +fit for a king;2852 +angel corpse;2853 +the audition;2854 +helalyn flowers;2855 +fleet foxes;2856 +the wiggles;2857 +clouds;2858 +peter cetera;2859 +wreckshop family;2860 +the mistake;2861 +lacrimosa;2862 +carpenters;2863 +the crabb family;2864 +twilight fauna;2865 +anton n dvo k;2866 +patti page;2867 +dawnbringer;2868 +bachman-turner overdrive;2869 +love like blood;2870 +pat mcgee band;2871 +shedaisy;2872 +the other ones;2873 +hatebreed;2874 +iamamiwhoami;2875 +showbread;2876 +thyx;2877 +face to face;2878 +bonnie owens;2879 +this wild life;2880 +adrienne young;2881 +tombs;2882 +f.k.ü.;2883 +carl nielsen;2884 +trouble;2885 +peter wolf;2886 +shout out louds;2887 +new york philharmonic;2888 +paul and storm;2889 +the dickies;2890 +hussein fatal;2891 +a tribe called quest;2892 +jade 4u;2893 +bonobo;2894 +alphabeat;2895 +gladys knight;2896 +tilt;2897 +jacqueline du pr ;2898 +boyz ii men;2899 +blood oranges;2900 +scala & kolacny brothers;2901 +steel attack;2902 +vienna teng;2903 +nunslaughter;2904 +roxy music;2905 +benny benassi;2906 +feargal sharkey;2907 +willie dixon;2908 +mary j. blige;2909 +ghost town;2910 +george ezra;2911 +rose cousins;2912 +the stone roses;2913 +mc5;2914 +go west;2915 +knut;2916 +the head and the heart;2917 +room eleven;2918 +simon and garfunkel;2919 +wilson pickett;2920 +the amboy dukes;2921 +walk the moon;2922 +abgott;2923 +truly;2924 +the louvin brothers;2925 +melanie c;2926 +enchant;2927 +duffy;2928 +union;2929 +great white;2930 +the violet burning;2931 +kat-tun;2932 +mercyme;2933 +elmore james;2934 +johnny horton;2935 +dreams of sanity;2936 +vázquez sounds;2937 +kraftwerk;2938 +cool hand luke;2939 +country joe mcdonald;2940 +abandoned pools;2941 +the swell season;2942 +3 inches of blood;2943 +rocky loves emily;2944 +whores.;2945 +natalie grant;2946 +frank proffitt;2947 +red fang;2948 +jason mraz;2949 +barefoot truth;2950 +lee aaron;2951 +frank hutchison;2952 +kasey chambers;2953 +sick of it all;2954 +girls in hawaii;2955 +geoff farina;2956 +rory gallagher;2957 +out of eden;2958 +mø;2959 +darkthrone;2960 +eddie money;2961 +envy on the coast;2962 +virgin prunes;2963 +mississippi sheiks;2964 +capitol steps;2965 +battery;2966 +hilary duff;2967 +betraying the martyrs;2968 +stray cats;2969 +the groundhogs;2970 +thieves and villains;2971 +la roux;2972 +southern raiders band;2973 +cam'ron;2974 +mississippi fred mcdowell;2975 +gary u.s. bonds;2976 +matt duke;2977 +stillborn;2978 +mnemic;2979 +jerry cantrell;2980 +clannad;2981 +mychildren mybride;2982 +dope;2983 +his hero is gone;2984 +deltron 3030;2985 +nebelhexë;2986 +angelic upstarts;2987 +bebo norman;2988 +kb;2989 +patricia barber;2990 +tsol;2991 +cathedral;2992 +glenn kaiser;2993 +peter koppes;2994 +the hunna;2995 +peaches;2996 +bryan adams;2997 +michael kiske;2998 +sigrid;2999 +gordon bok;3000 +the vamps;3001 +burning witches;3002 +the twilight singers;3003 +teyana taylor;3004 +robbie robertson;3005 +black veil brides;3006 +corbin-hanner band;3007 +white denim;3008 +see you next tuesday;3009 +corey hart;3010 +shy;3011 +visions of atlantis;3012 +pyrexia;3013 +rah digga;3014 +killwhitneydead;3015 +austra;3016 +yung joc;3017 +sevendust;3018 +miles kane;3019 +albert hammond, jr.;3020 +the sleepy jackson;3021 +quarterflash;3022 +baba brinkman;3023 +gautier capu on;3024 +heather dale;3025 +hinder;3026 +evoken;3027 +kardinal offishall;3028 +jett rebel;3029 +n-dubz;3030 +marcia ball;3031 +bucks fizz;3032 +freddie jackson;3033 +steve grand;3034 +leonard pennario;3035 +summoning;3036 +blaqk audio;3037 +the sisters of mercy;3038 +doyle bramhall ii;3039 +dominici;3040 +al b. sure!;3041 +giant sand;3042 +colosseum;3043 +johannes moser;3044 +yeasayer;3045 +unearth;3046 +oneiroid psychosis;3047 +sheila e.;3048 +alicia de larrocha;3049 +last tuesday;3050 +the bonzo dog doo-dah band;3051 +gilbert and sullivan;3052 +this day & age;3053 +anekdoten;3054 +greg lake;3055 +mike scott;3056 +black tide;3057 +colony 5;3058 +the malibooz;3059 +adam ant;3060 +pacewon;3061 +queensrÿche;3062 +the ames brothers;3063 +rooster;3064 +rare bird;3065 +justin nozuka;3066 +elle milano;3067 +yacht;3068 +neville marriner;3069 +faith no more;3070 +kool & the gang;3071 +fun lovin' criminals;3072 +yann tiersen;3073 +schäffer the darklord;3074 +aiden;3075 +metanoia;3076 +the high dials;3077 +charles bradley;3078 +paul gilbert;3079 +malvina reynolds;3080 +iron & wine;3081 +saturday looks good to me;3082 +viktor vaughn;3083 +isgaard;3084 +frank sinatra;3085 +alice cooper;3086 +passenger;3087 +michael nesmith;3088 +ancient;3089 +liza anne;3090 +the magic numbers;3091 +seraphim shock;3092 +abney park;3093 +guerilla maab;3094 +orphaned land;3095 +jack savoretti;3096 +zombina and the skeletones;3097 +leon fleisher;3098 +rick springfield;3099 +the left rights;3100 +starflyer 59;3101 +2 brothers on the 4th floor;3102 +emery;3103 +c.c. catch;3104 +mick taylor;3105 +good rats;3106 +blackmore's night;3107 +twisted sister;3108 +boney james;3109 +cancer;3110 +maria jo o pires;3111 +meiko;3112 +cass mccombs;3113 +deep dish;3114 +information society;3115 +blackie and the rodeo kings;3116 +the fold;3117 +ed harcourt;3118 +ramshackle glory;3119 +tom misch;3120 +bebe winans;3121 +joni mitchell;3122 +elizabeth shepherd;3123 +lil boosie;3124 +celluloide;3125 +house of lords;3126 +j.d. souther;3127 +midori goto;3128 +shenandoah;3129 +averi;3130 +modwheelmood;3131 +betty who;3132 +burst;3133 +pete shelley;3134 +jon bon jovi;3135 +x-perience;3136 +xentrix;3137 +grinderman;3138 +hem;3139 +the impressions;3140 +sylosis;3141 +the gregory brothers;3142 +macklemore;3143 +lizz wright;3144 +sawyer brown;3145 +capercaillie;3146 +sam & dave;3147 +the germs;3148 +salt-n-pepa;3149 +big sean;3150 +stornoway;3151 +arthur rubinstein;3152 +cock robin;3153 +big daddy;3154 +fernando ortega;3155 +ted nugent;3156 +coptic rain;3157 +kat deluna;3158 +wolfsheim;3159 +graham central station;3160 +charles harrison;3161 +lil jon & the east side boyz;3162 +lovedrug;3163 +our last night;3164 +mura masa;3165 +lacuna coil;3166 +luke doucet;3167 +punchline;3168 +animal logic;3169 +big bang;3170 +sieges even;3171 +g.g.f.h.;3172 +tyler lyle;3173 +the boswell sisters;3174 +fightstar;3175 +kevin rudolf;3176 +dangerous toys;3177 +comeback kid;3178 +wild orchid;3179 +one direction;3180 +electric six;3181 +the corrs;3182 +christy nockels;3183 +hillsong;3184 +sham 69;3185 +hurt;3186 +clint black;3187 +chris hillman & herb pedersen;3188 +def leppard;3189 +plants and animals;3190 +jack bruce;3191 +thalía;3192 +arthur crudup;3193 +phil wickham;3194 +king gizzard & the lizard wizard;3195 +beautiful eulogy;3196 +the last bison;3197 +caravan;3198 +the wonder stuff;3199 +jeff williams;3200 +sebadoh;3201 +jets overhead;3202 +golden smog;3203 +jonna lee;3204 +the faceless;3205 +daniel lanois;3206 +the judds;3207 +paragon;3208 +vienna philharmonic;3209 +electric president;3210 +tenth avenue north;3211 +solomon cutner;3212 +vnv nation;3213 +system syn;3214 +eric lindell;3215 +jenny lewis;3216 +the flower kings;3217 +chicago;3218 +stacey q;3219 +ark;3220 +chingo bling;3221 +isac elliot;3222 +penumbra;3223 +cypress hill;3224 +landon pigg;3225 +collide;3226 +mick ronson;3227 +fall of the leafe;3228 +melissa etheridge;3229 +suicidal tendencies;3230 +joshua kadison;3231 +the spill canvas;3232 +eclipse;3233 +within the ruins;3234 +haemorrhage;3235 +deliverance;3236 +robert pollard;3237 +paul kelly;3238 +alesana;3239 +the big pink;3240 +e-rotic;3241 +the books;3242 +h.p. lovecraft historical society;3243 +argent;3244 +nivea;3245 +mario;3246 +the fiery furnaces;3247 +atc;3248 +matt and kim;3249 +tobymac;3250 +lcd soundsystem;3251 +ant & dec;3252 +howe gelb;3253 +hozier;3254 +astarte;3255 +anathallo;3256 +basia bulat;3257 +tad morose;3258 +smp;3259 +greensky bluegrass;3260 +holly miranda;3261 +ub40;3262 +d12;3263 +scott miller;3264 +chicane;3265 +the faint;3266 +cream;3267 +archive;3268 +deicide;3269 +legendary shack shakers;3270 +guano apes;3271 +wolfgun;3272 +typhoon;3273 +pile;3274 +the philosopher kings;3275 +black grape;3276 +kotipelto;3277 +david lee murphy;3278 +fish;3279 +nekromantix;3280 +the chordettes;3281 +sherban lupu;3282 +darlene zschech;3283 +the henry girls;3284 +ida cox;3285 +peter & gordon;3286 +fear, and loathing in las vegas;3287 +jme;3288 +blood on the dance floor;3289 +electric light orchestra;3290 +romeo;3291 +mike heron;3292 +kendrick lamar;3293 +spock's beard;3294 +the bunny the bear;3295 +sweetbox;3296 +mac miller;3297 +spazz;3298 +liars;3299 +98°;3300 +blood duster;3301 +make do and mend;3302 +cheri dennis;3303 +gerald levert;3304 +chris tomlin;3305 +all saints;3306 +ghost ship;3307 +young the giant;3308 +jim james;3309 +the unseen;3310 +whitesnake;3311 +ciara;3312 +seventh day slumber;3313 +the b-52's;3314 +crime & the city solution;3315 +brentalfloss;3316 +gene clark;3317 +nouvelle vague;3318 +don johnson big band;3319 +shwayze;3320 +cat rapes dog;3321 +poisonblack;3322 +the wildhearts;3323 +bruce hornsby and the range;3324 +logic;3325 +vaux;3326 +suzy bogguss;3327 +sarke;3328 +charlie louvin;3329 +wild child;3330 +icons of filth;3331 +tarnation;3332 +thousand foot krutch;3333 +nikki webster;3334 +wolfmother;3335 +samuel barber;3336 +panda bear;3337 +ganggajang;3338 +rosetta stone;3339 +sonia disappearfear;3340 +the s.o.s. band;3341 +w.a.s.p.;3342 +silverstein;3343 +tin machine;3344 +jennifer warnes;3345 +andru donalds;3346 +olympos mons;3347 +cerebral fix;3348 +glenn frey;3349 +suzi quatro;3350 +sons of the pioneers;3351 +venetian princess;3352 +delirious?;3353 +lecrae;3354 +marty robbins;3355 +jeannie seely;3356 +the psychedelic ensemble;3357 +glenn medeiros;3358 +bleed from within;3359 +third world;3360 +alison krauss;3361 +dj shadow;3362 +a static lullaby;3363 +maps & atlases;3364 +james taylor;3365 +mekong delta;3366 +easy star all-stars;3367 +aura noir;3368 +santana;3369 +the gadjits;3370 +can;3371 +deepspace 5;3372 +leslie west;3373 +fr d ric chopin;3374 +sundara karma;3375 +powerman 5000;3376 +dutch rebelle;3377 +bones brigade;3378 +the browning;3379 +peter andre;3380 +connie francis;3381 +smooth;3382 +majesty;3383 +matthew dear;3384 +fionn regan;3385 +nuclear assault;3386 +over the rhine;3387 +magellan;3388 +zoot woman;3389 +shyne;3390 +kidneythieves;3391 +racoon;3392 +ironsword;3393 +alessandro scarlatti;3394 +the appleseed cast;3395 +operation ivy;3396 +akron/family;3397 +qkumba zoo;3398 +the chasm;3399 +the style council;3400 +method man;3401 +the halliard;3402 +boy george;3403 +tarot;3404 +delays;3405 +cromok;3406 +honeymoon suite;3407 +hercules & love affair;3408 +lemuria;3409 +the kelly family;3410 +tweet;3411 +tru;3412 +lawnmower deth;3413 +no use for a name;3414 +dogwood;3415 +penitent;3416 +capture the crown;3417 +hawksley workman;3418 +the drifters;3419 +school of seven bells;3420 +james keelaghan;3421 +the 69 eyes;3422 +insane clown posse;3423 +save ferris;3424 +trust;3425 +atb;3426 +todd rundgren;3427 +hank cochran;3428 +forever the sickest kids;3429 +new riders of the purple sage;3430 +georg philipp telemann;3431 +crippled black phoenix;3432 +paul mccartney;3433 +ryan adams and the cardinals;3434 +silent cry;3435 +king creosote;3436 +run the jewels;3437 +the kings;3438 +steve goodman;3439 +nitty gritty dirt band;3440 +eric bibb;3441 +editors;3442 +blessed by a broken heart;3443 +civil twilight;3444 +children of bodom;3445 +michael jackson;3446 +richie sambora;3447 +willam;3448 +devildriver;3449 +e.s.g.;3450 +sananda maitreya;3451 +babbie mason;3452 +the museum;3453 +dan zanes;3454 +e-type;3455 +gidon kremer;3456 +al denson;3457 +aeon;3458 +kenny rogers;3459 +the tear garden;3460 +joshua bell;3461 +set your goals;3462 +le tigre;3463 +holly dunn;3464 +ignacy jan paderewski;3465 +immortal;3466 +108;3467 +ann beretta;3468 +dezarie;3469 +pete seeger;3470 +jan & dean;3471 +nina kinert;3472 +the lonely forest;3473 +protest the hero;3474 +diorama;3475 +khoma;3476 +japan;3477 +jim brickman;3478 +halifax;3479 +rebecca lynn howard;3480 +flobots;3481 +the new power generation;3482 +gods paparazzi;3483 +shannon curfman;3484 +roy woods;3485 +varsity fanclub;3486 +dave stewart;3487 +mumford & sons;3488 +syd matters;3489 +the nerve agents;3490 +kula shaker;3491 +luke sital-singh;3492 +john wesley harding;3493 +venom;3494 +melanie doane;3495 +the hippos;3496 +jessi colter;3497 +the movielife;3498 +babybird;3499 +bodyfarm;3500 +tara maclean;3501 +jackson browne;3502 +within temptation;3503 +cash cash;3504 +warren zevon;3505 +eva cassidy;3506 +billy ray cyrus;3507 +justin timberlake;3508 +the antlers;3509 +john elefante;3510 +angel;3511 +jaap schr der;3512 +evermore;3513 +destroy the runner;3514 +the black crowes;3515 +tiga;3516 +bury your dead;3517 +slowdive;3518 +machine head;3519 +c-murder;3520 +dirty;3521 +fujiya & miyagi;3522 +agonoize;3523 +hundredth;3524 +prong;3525 +nikki flores;3526 +cyanotic;3527 +jordan pruitt;3528 +u.s. bombs;3529 +a halo called fred;3530 +don williams;3531 +chester watson;3532 +noa;3533 +my passion;3534 +george harrison;3535 +scandroid;3536 +sister sin;3537 +hot snakes;3538 +black flag;3539 +christie;3540 +christoph eschenbach;3541 +slim gaillard;3542 +gravediggaz;3543 +the northern pikes;3544 +miranda sex garden;3545 +colin blunstone;3546 +the rasmus;3547 +nazareth;3548 +degarmo and key;3549 +earth crisis;3550 +the foreign exchange;3551 +uncle tupelo;3552 +kitty wells;3553 +karate high school;3554 +weeping tile;3555 +skinny puppy;3556 +audience;3557 +devotchka;3558 +john lennon;3559 +elf power;3560 +teresa brewer;3561 +heinrich schiff;3562 +6lack;3563 +anti-depressive delivery;3564 +the moffatts;3565 +lynn anderson;3566 +mordacious;3567 +robert palmer;3568 +seabound;3569 +black star riders;3570 +bryan rice;3571 +j.b. lenoir;3572 +the yards;3573 +the stupid stupid henchmen;3574 +tony rice;3575 +barbecue bob;3576 +dr. hook & the medicine show;3577 +garrison starr;3578 +union 13;3579 +jay sean;3580 +pretty willie;3581 +oceano;3582 +captain beefheart and the magic band;3583 +markéta irglová;3584 +wolfe tones;3585 +crumbsuckers;3586 +towers of london;3587 +impaled nazarene;3588 +big tent revival;3589 +hans theessink;3590 +the amity affliction;3591 +animal liberation orchestra;3592 +tower of power;3593 +vanessa bell armstrong;3594 +tom fogerty;3595 +pianos become the teeth;3596 +poppy;3597 +the knack;3598 +fields of the nephilim;3599 +peter and the test tube babies;3600 +cory branan;3601 +cherrelle;3602 +palaye royale;3603 +southside johnny & the asbury jukes;3604 +heideroosjes;3605 +the busters;3606 +dave edmunds;3607 +buck 65;3608 +the lost trailers;3609 +steam powered giraffe;3610 +lydia lunch;3611 +washboard sam;3612 +big time rush;3613 +nlt;3614 +old 97's;3615 +rupert hine;3616 +jon mclaughlin;3617 +acid drinkers;3618 +heaven & hell;3619 +george hamilton iv;3620 +scott joplin;3621 +the berzerker;3622 +jonatha brooke;3623 +iggy azalea;3624 +trijntje oosterhuis;3625 +cee lo green;3626 +wig wam;3627 +mark heard;3628 +phil manzanera;3629 +the story;3630 +kokomo arnold;3631 +the beau brummels;3632 +acid bath;3633 +talisman;3634 +mc chris;3635 +the del mccoury band;3636 +ty segall;3637 +boysetsfire;3638 +the ducky boys;3639 +delta moon;3640 +thumb;3641 +blacklisted;3642 +purity ring;3643 +anders manga;3644 +burn halo;3645 +how to dress well;3646 +maxnormal.tv;3647 +binoculers;3648 +lou barlow;3649 +doug sahm;3650 +gary allan;3651 +jan wayne;3652 +mörk gryning;3653 +danko jones;3654 +dover;3655 +robben ford;3656 +black breath;3657 +lovespirals;3658 +sérgio mendes;3659 +rufus;3660 +kingcrow;3661 +dmitri shostakovich;3662 +ghostface killah;3663 +lyriel;3664 +agathodaimon;3665 +hezekiah walker;3666 +nonpoint;3667 +balzac;3668 +lunatica;3669 +ella mae morse;3670 +toyah;3671 +nik kershaw;3672 +hammerfall;3673 +jmsn;3674 +speaker;3675 +whitechapel;3676 +haddaway;3677 +grace vanderwaal;3678 +the tubes;3679 +eric church;3680 +the o.c. supertones;3681 +frozen ghost;3682 +98 mute;3683 +bobby darin;3684 +voxtrot;3685 +the darkness;3686 +paris;3687 +killswitch engage;3688 +jessica lea mayfield;3689 +n-trance;3690 +hank williams, jr.;3691 +b5;3692 +thunderstone;3693 +north mississippi allstars;3694 +angry samoans;3695 +alexis korner;3696 +youssou n'dour;3697 +jet set satellite;3698 +boomkat;3699 +leif ove andsnes;3700 +ektomorf;3701 +ceremony;3702 +isley jasper isley;3703 +r.a. the rugged man;3704 +the twilight sad;3705 +the electric prunes;3706 +dream street;3707 +the yardbirds;3708 +turisas;3709 +celldweller;3710 +wigwam;3711 +paul carrack;3712 +dads;3713 +per gessle;3714 +eugene mcguinness;3715 +hardline;3716 +patti labelle;3717 +busta rhymes;3718 +rasputina;3719 +antique;3720 +schoolboy q;3721 +beat happening;3722 +punch brothers;3723 +keshia chanté;3724 +bob carlisle;3725 +daan;3726 +imperative reaction;3727 +after the fire;3728 +marc and the mambas;3729 +minnie driver;3730 +secondhand serenade;3731 +the byrds;3732 +bread;3733 +talib kweli;3734 +nelly;3735 +hagalaz' runedance;3736 +stick to your guns;3737 +the virus;3738 +snow;3739 +james morrison;3740 +yes;3741 +neuroactive;3742 +misanthrope;3743 +morgana lefay;3744 +che'nelle;3745 +hackneyed;3746 +wilhelm backhaus;3747 +warren haynes;3748 +proclamation;3749 +andy griggs;3750 +the bongos;3751 +corrosion of conformity;3752 +paloma faith;3753 +the japanese house;3754 +tizzy bac;3755 +agathocles;3756 +kari peitsamo;3757 +mýa;3758 +ignaz friedman;3759 +blitz;3760 +dyscarnate;3761 +the hidden cameras;3762 +egypt central;3763 +noggin toboggan;3764 +sadistik;3765 +peter gabriel;3766 +cinderella;3767 +sebastian sturm;3768 +psycroptic;3769 +sylver;3770 +jaymay;3771 +nahemah;3772 +dubioza kolektiv;3773 +the pogues;3774 +the arrogant sons of bitches;3775 +nelson freire;3776 +mastedon;3777 +leonid kogan;3778 +ezra furman;3779 +ohgr;3780 +edward maya;3781 +wings;3782 +freya;3783 +skye;3784 +ablaze my sorrow;3785 +gerry rafferty;3786 +franz schubert;3787 +peccatum;3788 +bananafishbones;3789 +claude debussy;3790 +eurythmics;3791 +will oldham;3792 +fiona boyes;3793 +cellar darling;3794 +public image ltd.;3795 +fireflight;3796 +afu-ra;3797 +little mix;3798 +power quest;3799 +emmy the great;3800 +sub7even;3801 +gwen stefani;3802 +playradioplay!;3803 +aaron neville;3804 +the stryder;3805 +lullacry;3806 +kelli ali;3807 +bow wow;3808 +igor stravinsky;3809 +grade;3810 +tall dwarfs;3811 +rbd;3812 +despised icon;3813 +blues magoos;3814 +the long winters;3815 +majid jordan;3816 +vincenzo bellini;3817 +loretta lynn;3818 +kenny wayne shepherd;3819 +bleeding through;3820 +cursive;3821 +linus of hollywood;3822 +g-unit;3823 +the casket lottery;3824 +kingston wall;3825 +kate voegele;3826 +amanda lear;3827 +vicky beeching;3828 +colin james;3829 +elvis costello & the attractions;3830 +dana dirksen;3831 +c sar franck;3832 +dog fashion disco;3833 +josé gonzález;3834 +the joy formidable;3835 +elly ney;3836 +meliah rage;3837 +tim moore;3838 +james blunt;3839 +american pleasure club;3840 +nicole scherzinger;3841 +the bad shepherds;3842 +the fabulous thunderbirds;3843 +i can make a mess like nobody's business;3844 +three plus;3845 +julie roberts;3846 +tribe;3847 +luke bryan;3848 +saxon;3849 +philip glass;3850 +bobby womack;3851 +triumph;3852 +veda hille;3853 +coldrain;3854 +en vogue;3855 +amy winehouse;3856 +bonnie pink;3857 +the doc watson family;3858 +bad company;3859 +fuck;3860 +cradle of filth;3861 +gorky's zygotic mynci;3862 +buck owens;3863 +elle king;3864 +samael;3865 +meryn cadell;3866 +nocturnal rites;3867 +ghost dance;3868 +kristy lee cook;3869 +the script;3870 +jake owen;3871 +death cab for cutie;3872 +the forgotten rebels;3873 +beaver;3874 +tom rush;3875 +david rock feinstein;3876 +oathbreaker;3877 +odetta;3878 +compton's most wanted;3879 +psy'aviah;3880 +big ed;3881 +john miles;3882 +shellac;3883 +turin brakes;3884 +eternal tears of sorrow;3885 +kodak black;3886 +slick rick;3887 +code orange;3888 +gioacchino rossini;3889 +marc andr hamelin;3890 +ulver;3891 +la toya jackson;3892 +path of resistance;3893 +laura fygi;3894 +tom mcrae;3895 +sitti;3896 +frank stokes;3897 +anorexia nervosa;3898 +gabriel cyphre;3899 +the jon spencer blues explosion;3900 +m-flo;3901 +jason donovan;3902 +sean paul;3903 +girls;3904 +504 boyz;3905 +bring me the horizon;3906 +shelby lynne;3907 +pierre laurent aimard;3908 +jim messina;3909 +the boyz;3910 +hank thompson;3911 +hands;3912 +zakk wylde;3913 +nikka costa;3914 +nelly furtado;3915 +fairground attraction;3916 +born of osiris;3917 +fenix tx;3918 +robert plant;3919 +robert casadesus;3920 +paul van dyk;3921 +glenn kaiser band;3922 +daughters;3923 +saraya;3924 +rae sremmurd;3925 +norma jean;3926 +the plot in you;3927 +wild nothing;3928 +apocalyptica;3929 +tony! toni! toné!;3930 +olivia newton-john;3931 +keith richards;3932 +elizabeth cook;3933 +outlandish;3934 +halford;3935 +susan ashton;3936 +doves;3937 +queen + paul rodgers;3938 +wishing chair;3939 +pseudo echo;3940 +crazyeightyeight;3941 +red lights flash;3942 +neon indian;3943 +erick sermon;3944 +the juliana theory;3945 +larry gatlin & the gatlin brothers;3946 +paul whiteman;3947 +missy elliott;3948 +the chiffons;3949 +allison iraheta;3950 +centvrion;3951 +the 5th dimension;3952 +dighayzoose;3953 +nina nastasia;3954 +shadowside;3955 +5 seconds of summer;3956 +asaf avidan;3957 +cady groves;3958 +old man luedecke;3959 +the chap;3960 +john maus;3961 +tom petty and the heartbreakers;3962 +have a nice life;3963 +breach of trust;3964 +claudio arrau;3965 +toro y moi;3966 +the tony danza tapdance extravaganza;3967 +oscar brand;3968 +john mccormack;3969 +anti-nowhere league;3970 +shearer;3971 +j.j. cale;3972 +iyaz;3973 +ice ages;3974 +the city harmonic;3975 +bruce mcculloch;3976 +the color changin' click;3977 +crack the sky;3978 +the moldy peaches;3979 +coolio;3980 +jaill;3981 +mud;3982 +hodgy beats;3983 +clap your hands say yeah;3984 +badly drawn boy;3985 +ewert and the two dragons;3986 +tystnaden;3987 +janie fricke;3988 +dottie west;3989 +witherscape;3990 +目黒将司 (shoji meguro);3991 +mnek;3992 +kurt nilsen;3993 +psychic tv;3994 +the boomtown rats;3995 +nena;3996 +stephin merritt;3997 +nausea;3998 +molly venter;3999 +rasaq;4000 +olly murs;4001 +хелависа;4002 +coko;4003 +scarface;4004 +sam smith;4005 +midnight juggernauts;4006 +pulley;4007 +theresa sokyrka;4008 +jacob banks;4009 +bomb the music industry!;4010 +meredith andrews;4011 +yearning;4012 +ron sexsmith;4013 +joseph haydn;4014 +einherjer;4015 +four tops;4016 +giles, giles and fripp;4017 +iona brown;4018 +bon jovi;4019 +kunt and the gang;4020 +motionless in white;4021 +sabrina;4022 +jillian aversa;4023 +the persuasions;4024 +tub ring;4025 +sacred warrior;4026 +susan boyle;4027 +la the darkman;4028 +savage garden;4029 +lindisfarne;4030 +jag panzer;4031 +dana key;4032 +wouter hamel;4033 +peter green;4034 +jill scott;4035 +wreck and reference;4036 +vanilla fudge;4037 +aerosmith;4038 +megafaun;4039 +poundhound;4040 +2 skinnee j's;4041 +the call;4042 +sonny boy williamson i;4043 +possessed;4044 +annie;4045 +suburban legends;4046 +the mutton birds;4047 +cibo matto;4048 +lorna shore;4049 +terry callier;4050 +selah sue;4051 +derek webb;4052 +parliament;4053 +sister machine gun;4054 +the badlees;4055 +the regrettes;4056 +marlon roudette;4057 +albert king;4058 +rebelution;4059 +shura cherkassky;4060 +dave rodgers;4061 +skip james;4062 +caedmon's call;4063 +asp;4064 +souldecision;4065 +savoir adore;4066 +nathaniel rateliff;4067 +the temperance movement;4068 +dragonland;4069 +isaac alb niz;4070 +falling up;4071 +stabilo;4072 +christ analogue;4073 +big mountain;4074 +sade;4075 +the casting out;4076 +gene autry;4077 +manfred mann;4078 +drive-by truckers;4079 +javier mendoza;4080 +alyson stoner;4081 +blind lemon jefferson;4082 +lowkey;4083 +brad paisley;4084 +jane child;4085 +i declare war;4086 +leo jan ek;4087 +lonestar;4088 +boards of canada;4089 +don henley;4090 +choclair;4091 +obsc(y)re;4092 +donnie mcclurkin;4093 +wall of voodoo;4094 +tony bennett;4095 +hank snow;4096 +poison the well;4097 +fancy;4098 +unbelievable truth;4099 +jet life;4100 +rory block;4101 +rachael lampa;4102 +the platters;4103 +tahiti 80;4104 +the gathering;4105 +brett dennen;4106 +lily allen;4107 +puffy amiyumi;4108 +iamx;4109 +tree63;4110 +bee gees;4111 +e.g. daily;4112 +narnia;4113 +peter green splinter group;4114 +gram parsons;4115 +facing new york;4116 +kalmah;4117 +hot water music;4118 +blessthefall;4119 +general public;4120 +cornershop;4121 +owen pallett;4122 +truth hurts;4123 +quorthon;4124 +kill your idols;4125 +planet funk;4126 +leonardo's bride;4127 +jimmy rushing;4128 +the title;4129 +dog eat dog;4130 +zucchero;4131 +mind.in.a.box;4132 +mainstay;4133 +graham nash;4134 +therion;4135 +bad boys blue;4136 +swizz beatz;4137 +joey + rory;4138 +matthew herbert;4139 +krewella;4140 +lou rhodes;4141 +linda perry;4142 +the pointer sisters;4143 +fit for an autopsy;4144 +yelworc;4145 +jeffrey lewis;4146 +arghoslent;4147 +andy park;4148 +uriah heep;4149 +disciple;4150 +sodom;4151 +beth nielsen chapman;4152 +chuck ragan;4153 +spoons;4154 +haerts;4155 +ice nine kills;4156 +rosie thomas;4157 +guerilla toss;4158 +dizzee rascal;4159 +g4;4160 +mendeed;4161 +empire of the sun;4162 +fergie;4163 +mishka;4164 +tom jones;4165 +the brothers four;4166 +racer x;4167 +clipping.;4168 +stiff little fingers;4169 +the ghost of a saber tooth tiger;4170 +ultimatum;4171 +odyssey eurobeat;4172 +tony banks;4173 +shaggy;4174 +kotoko;4175 +nothingface;4176 +mellowhype;4177 +anthony green;4178 +bulldozer;4179 +abigail williams;4180 +gangsta boo;4181 +jonny lang;4182 +j. cole;4183 +edvard grieg;4184 +the residents;4185 +luther allison;4186 +jean philippe rameau;4187 +randy newman;4188 +jeff the brotherhood;4189 +king missile;4190 +cloud nothings;4191 +fiona;4192 +the walkmen;4193 +nicola benedetti;4194 +birmingham 6;4195 +edge of dawn;4196 +nathan milstein;4197 +the paul butterfield blues band;4198 +he is legend;4199 +ol' dirty bastard;4200 +steve miller band;4201 +craig's brother;4202 +beracah;4203 +new edition;4204 +falconshield;4205 +childish gambino;4206 +am & shawn lee;4207 +unkle;4208 +silver jews;4209 +the interrupters;4210 +william shatner;4211 +adrian belew;4212 +scanner;4213 +slash;4214 +sweatshop union;4215 +dayna kurtz;4216 +krisma;4217 +ferraby lionheart;4218 +new years day;4219 +madchild;4220 +tohoshinki;4221 +busted;4222 +tyler bryant & the shakedown;4223 +vanessa hudgens;4224 +lady gaga;4225 +kosheen;4226 +circle ii circle;4227 +glee cast;4228 +forgotten tales;4229 +renaissance;4230 +lonnie johnson;4231 +swans;4232 +laura marling;4233 +against the current;4234 +ane brun;4235 +the buckinghams;4236 +art bears;4237 +rocky votolato;4238 +the soft boys;4239 +jonathan thulin;4240 +andreas johnson;4241 +pages;4242 +steve moakler;4243 +a.c. newman;4244 +showaddywaddy;4245 +bart davenport;4246 +the streets;4247 +allstar weekend;4248 +death grips;4249 +seventh avenue;4250 +grandmaster flash;4251 +a split-second;4252 +sense field;4253 +maisey rika;4254 +haken;4255 +sharon needles;4256 +arcangelo corelli;4257 +teen suicide;4258 +blue highway;4259 +the megas;4260 +noxious emotion;4261 +keldian;4262 +asian dub foundation;4263 +h.e.r.;4264 +girlpool;4265 +eddie degarmo;4266 +steve taylor;4267 +alex story;4268 +willy porter;4269 +aura dione;4270 +melanie b;4271 +az;4272 +chris isaak;4273 +captain tractor;4274 +anita baker;4275 +anne akiko meyers;4276 +josh rouse;4277 +noname;4278 +tina guo;4279 +the wannadies;4280 +the romantics;4281 +firewind;4282 +less than jake;4283 +owain phyfe;4284 +drag the river;4285 +keith sweat;4286 +kari jobe;4287 +dispatch;4288 +john stewart;4289 +hellhammer;4290 +reflection eternal;4291 +the last dance;4292 +ultimate fakebook;4293 +nomad;4294 +coal chamber;4295 +juice;4296 +gotthard;4297 +richard wagner;4298 +the strypes;4299 +felix mendelssohn bartholdy;4300 +lou gramm;4301 +necro;4302 +vladimir ashkenazy;4303 +the datsuns;4304 +green jellÿ;4305 +johnny duncan;4306 +thingy;4307 +jimmie rodgers;4308 +paul brady;4309 +hazel dickens;4310 +claude king;4311 +wynardtage;4312 +craig morgan;4313 +japandroids;4314 +the almanac singers;4315 +memphis slim;4316 +eddie rabbitt;4317 +mortification;4318 +escape the fate;4319 +tonight alive;4320 +tyler, the creator;4321 +cubanate;4322 +alvin youngblood hart;4323 +steel train;4324 +natasha thomas;4325 +violent soho;4326 +laika;4327 +michael bublé;4328 +folly & the hunter;4329 +nektar;4330 +carnifex;4331 +johan;4332 +matthew good;4333 +backyard babies;4334 +jim kweskin;4335 +beat crusaders;4336 +bullet for my valentine;4337 +oceans ate alaska;4338 +the communards;4339 +quo vadis;4340 +alessi brothers;4341 +1910 fruitgum company;4342 +attila;4343 +christian bautista;4344 +ian anderson;4345 +the grates;4346 +ethel waters;4347 +urthboy;4348 +burlap to cashmere;4349 +nails;4350 +pyotr ilyich tchaikovsky;4351 +keely smith;4352 +milemarker;4353 +truls m rk;4354 +snoop dogg;4355 +akrobatik;4356 +jorge bolet;4357 +jonny diaz;4358 +killer dwarfs;4359 +birth control;4360 +write this down;4361 +high school football heroes;4362 +the frames;4363 +angelo branduardi;4364 +casey bill weldon;4365 +steve green;4366 +bill anderson;4367 +jin akanishi;4368 +kimbra;4369 +nevermore;4370 +garrick ohlsson;4371 +nolongerhuman;4372 +ewan maccoll;4373 +the incredible string band;4374 +hayden;4375 +body count;4376 +charlie parr;4377 +andrew w.k.;4378 +sarah blasko;4379 +vetiver;4380 +борис гребенщиков;4381 +stephen marley;4382 +sage francis;4383 +fischerspooner;4384 +the strokes;4385 +bootsauce;4386 +maurice ravel;4387 +mini mansions;4388 +heartsounds;4389 +vangelis;4390 +artension;4391 +bear's den;4392 +mystic circle;4393 +katie melua;4394 +the mission;4395 +buddy & julie miller;4396 +2 live crew;4397 +calexico;4398 +danielle peck;4399 +devil doll;4400 +the mad conductor;4401 +eliane elias;4402 +brutal truth;4403 +bootsy collins;4404 +saving abel;4405 +robby valentine;4406 +vader;4407 +midnattsol;4408 +jigsaw;4409 +bullets and octane;4410 +company of thieves;4411 +kylie minogue;4412 +sandi thom;4413 +norah jones;4414 +the dillards;4415 +bulletboys;4416 +high places;4417 +neon horse;4418 +anna ternheim;4419 +alessia cara;4420 +wolfgang schneiderhan;4421 +tzu;4422 +t. rex;4423 +treble charger;4424 +culture;4425 +gaelic storm;4426 +elliott smith;4427 +memoryhouse;4428 +the amazing rhythm aces;4429 +balance of power;4430 +coil;4431 +hot rod circuit;4432 +the guess who;4433 +fredrika stahl;4434 +da' t.r.u.t.h.;4435 +toh kay;4436 +gentle giant;4437 +roger whittaker;4438 +the dø;4439 +neil sedaka;4440 +the view;4441 +the lookouts;4442 +twrp;4443 +tinie tempah;4444 +dana winner;4445 +civil war;4446 +haujobb;4447 +the crucified;4448 +tv on the radio;4449 +gil scott-heron;4450 +marit larsen;4451 +robert calvert;4452 +ja rule;4453 +tina charles;4454 +ima robot;4455 +neva dinova;4456 +thaurorod;4457 +lou christie;4458 +scritti politti;4459 +whiskeytown;4460 +while she sleeps;4461 +kristine w;4462 +zilch;4463 +the avett brothers;4464 +the human league;4465 +ilse delange;4466 +tinashe;4467 +mc ren;4468 +exciter;4469 +papa roach;4470 +frank turner;4471 +sol invictus;4472 +anya marina;4473 +these new puritans;4474 +instalok;4475 +tom smith;4476 +maria muldaur;4477 +e-40;4478 +holly golightly;4479 +my bloody valentine;4480 +defiance;4481 +allison moorer;4482 +wynn stewart;4483 +haggard;4484 +all shall perish;4485 +fritz kreisler;4486 +dead prez;4487 +lenny kravitz;4488 +lagwagon;4489 +damian marley;4490 +icehouse;4491 +dionne warwick;4492 +the devil makes three;4493 +drive, she said;4494 +hollow haze;4495 +anita carter;4496 +h.e.a.t;4497 +slaves on dope;4498 +arsis;4499 +samson;4500 +swv;4501 +l.a. guns;4502 +hiatus kaiyote;4503 +quicksilver messenger service;4504 +lea michele;4505 +graf orlock;4506 +tiago iorc;4507 +great northern;4508 +ray wylie hubbard;4509 +super junior;4510 +jerry jeff walker;4511 +hocico;4512 +bukimina;4513 +stretch;4514 +anthony hamilton;4515 +mushroomhead;4516 +evergreen terrace;4517 +michael mcdonald;4518 +leroy hutson;4519 +structures;4520 +dance gavin dance;4521 +other people;4522 +linda davis;4523 +doc walker;4524 +rumer;4525 +chuck berry;4526 +shoffy;4527 +dickey lee;4528 +freddy fender;4529 +batmobile;4530 +the jimi hendrix experience;4531 +teddy pendergrass;4532 +bushwick bill;4533 +gary moore;4534 +arthur beatrice;4535 +hurrah!;4536 +tsunami bomb;4537 +thundra;4538 +herb alpert & the tijuana brass;4539 +the flashbulb;4540 +korpiklaani;4541 +the mendoza line;4542 +vashti bunyan;4543 +unknown mortal orchestra;4544 +jerry garcia;4545 +richard shindell;4546 +i fight dragons;4547 +late tuesday;4548 +chris connor;4549 +the chemical brothers;4550 +virgin steele;4551 +sybreed;4552 +dan le sac vs scroobius pip;4553 +lani hall;4554 +nero;4555 +twin shadow;4556 +gordon downie;4557 +aphrodite's child;4558 +bodyjar;4559 +magic man;4560 +baths;4561 +tender forever;4562 +of monsters and men;4563 +krypteria;4564 +jandek;4565 +r.i.o.;4566 +government issue;4567 +jane monheit;4568 +jeffree star;4569 +moby grape;4570 +silver convention;4571 +michelle wright;4572 +the shroud;4573 +joseph szigeti;4574 +les claypool;4575 +the kills;4576 +beth hart;4577 +bobo in white wooden houses;4578 +twilight force;4579 +larry sparks;4580 +eddie vedder;4581 +glen campbell;4582 +michael hedges;4583 +the red shore;4584 +gloria gaynor;4585 +m2m;4586 +altered images;4587 +youth lagoon;4588 +xv;4589 +kevorkian death cycle;4590 +the sugarcubes;4591 +cryptic slaughter;4592 +candy butchers;4593 +8ball;4594 +jhené aiko;4595 +marcelle meyer;4596 +gaither vocal band;4597 +the boy least likely to;4598 +dean martin;4599 +journey;4600 +jackie evancho;4601 +esperanza spalding;4602 +the time;4603 +tampa red;4604 +poison;4605 +demis roussos;4606 +maria solheim;4607 +living colour;4608 +brutality;4609 +avatar;4610 +katie armiger;4611 +paul wilbur;4612 +tokio hotel;4613 +larue;4614 +golden earring;4615 +saint etienne;4616 +the go! team;4617 +james gang;4618 +master p;4619 +billie holiday;4620 +they might be giants;4621 +paul simon;4622 +flashlight brown;4623 +dreezy;4624 +david byron;4625 +kim boyce;4626 +masta killa;4627 +dmx;4628 +flesh-n-bone;4629 +june carter cash;4630 +crucial conflict;4631 +persephone;4632 +asher roth;4633 +angel dust;4634 +johnny crash;4635 +amy ray;4636 +lang lang;4637 +two hours traffic;4638 +attrition;4639 +carole king;4640 +sarah mclachlan;4641 +adolf busch;4642 +absolution project;4643 +justin bieber;4644 +penny mclean;4645 +velvet belly;4646 +matt nathanson;4647 +holly cole;4648 +diana vickers;4649 +ella mai;4650 +mark eitzel;4651 +the associates;4652 +vortech;4653 +in strict confidence;4654 +helloween;4655 +chasing victory;4656 +ninety pound wuss;4657 +jackie gleason;4658 +be bop deluxe;4659 +lit;4660 +the bruisers;4661 +amanda jenssen;4662 +crowder;4663 +ulcerate;4664 +mewithoutyou;4665 +joe purdy;4666 +t-bone walker;4667 +sarah brightman;4668 +chihiro onitsuka;4669 +trophy eyes;4670 +the receiving end of sirens;4671 +king's x;4672 +chad brownlee;4673 +battlelore;4674 +refused;4675 +far-less;4676 +brandy;4677 +black stone cherry;4678 +regina spektor;4679 +house of pain;4680 +220 volt;4681 +ty herndon;4682 +tarja;4683 +aaron tippin;4684 +slightly stoopid;4685 +nic jones;4686 +animal collective;4687 +converge;4688 +freddie king;4689 +kelela;4690 +the samples;4691 +draconian;4692 +the klezmatics;4693 +rob crow;4694 +country joe and the fish;4695 +cage;4696 +benny sings;4697 +wolfstone;4698 +w-inds.;4699 +lin-manuel miranda;4700 +azealia banks;4701 +zap mama;4702 +death threat;4703 +will stratton;4704 +audio adrenaline;4705 +jars of clay;4706 +shamir;4707 +miranda cosgrove;4708 +ginuwine;4709 +hell razah;4710 +thy primordial;4711 +weh;4712 +jason aldean;4713 +philippe entremont;4714 +smog;4715 +benny hester;4716 +otis redding;4717 +the methadones;4718 +karnivool;4719 +tennessee ernie ford;4720 +bob rivers;4721 +r. kelly;4722 +gang starr;4723 +king crimson;4724 +as we fight;4725 +sons of butcher;4726 +of the wand & the moon;4727 +the cars;4728 +salt the wound;4729 +fair to midland;4730 +lydia;4731 +terri clark;4732 +chris chameleon;4733 +the project hate mcmxcix;4734 +shadow gallery;4735 +black francis;4736 +gym class heroes;4737 +bill nelson;4738 +an cafe;4739 +smokey robinson;4740 +the duhks;4741 +broadway;4742 +fetty wap;4743 +billy sprague;4744 +norther;4745 +six feet under;4746 +republica;4747 +liam finn;4748 +highway 101;4749 +maureen mcgovern;4750 +dim mak;4751 +the go-betweens;4752 +old man's child;4753 +fall out boy;4754 +mia x;4755 +bbmak;4756 +cannabis corpse;4757 +ludacris;4758 +creature feature;4759 +miss montreal;4760 +eric burdon & the animals;4761 +bumblefoot;4762 +origin;4763 +capital cities;4764 +doro;4765 +nox arcana;4766 +hateen;4767 +the band perry;4768 +metallica;4769 +buffalo springfield;4770 +the hooters;4771 +peaches & herb;4772 +krystal meyers;4773 +paul rodgers;4774 +memphis jug band;4775 +sofie;4776 +maurizio pollini;4777 +brook benton;4778 +die verbannten kinder evas;4779 +brainiac;4780 +bearstronaut;4781 +pierce the veil;4782 +matthew friedberger;4783 +victims family;4784 +hell or highwater;4785 +emerson drive;4786 +caro emerald;4787 +louis jordan;4788 +the osmonds;4789 +unspoken;4790 +craig cardiff;4791 +tomohisa yamashita;4792 +ari hest;4793 +dj jazzy jeff & the fresh prince;4794 +dj drama & lil wayne;4795 +ziggy;4796 +waters;4797 +シド (sid);4798 +jeannie c. riley;4799 +tilly and the wall;4800 +karen matheson;4801 +blind passengers;4802 +brotha lynch hung;4803 +harry nilsson;4804 +young money;4805 +marike jager;4806 +good shoes;4807 +tom tom club;4808 +animaniacs;4809 +solitude aeturnus;4810 +george strait;4811 +akinyele;4812 +the honorary title;4813 +carl wilson;4814 +irving;4815 +izzy stradlin;4816 +the carter family;4817 +gzr;4818 +axxis;4819 +marc e. bassy;4820 +chipmunk;4821 +gigi d'agostino;4822 +tindersticks;4823 +the dears;4824 +the ocean;4825 +raul malo;4826 +joel plaskett;4827 +trooper;4828 +arnold schoenberg;4829 +zayn;4830 +hellsongs;4831 +leftöver crack;4832 +the waterboys;4833 +levon helm;4834 +gehenna;4835 +force majeure;4836 +take 6;4837 +amy rigby;4838 +lil baby;4839 +north star;4840 +mott the hoople;4841 +dorsal atlântica;4842 +sabrina carpenter;4843 +julee cruise;4844 +blu cantrell;4845 +willard grant conspiracy;4846 +faron young;4847 +celtic woman;4848 +tony joe white;4849 +petal;4850 +titus andronicus;4851 +son house;4852 +hungry lights;4853 +eskimo callboy;4854 +marnie;4855 +seth walker;4856 +the herd;4857 +asobi seksu;4858 +david crosby;4859 +billy joe royal;4860 +jinkx monsoon;4861 +the replacements;4862 +iio;4863 +binärpilot;4864 +young guns;4865 +mel tormé;4866 +the baseballs;4867 +aphex twin;4868 +mike ness;4869 +snot;4870 +blind willie mctell;4871 +icon for hire;4872 +jeff tweedy;4873 +swollen members;4874 +carly rae jepsen;4875 +crystal viper;4876 +larry the cable guy;4877 +andre nickatina & equipto;4878 +raphael saadiq;4879 +mesmerize;4880 +in flames;4881 +kristy thirsk;4882 +headlights;4883 +deathspell omega;4884 +joan armatrading;4885 +red red meat;4886 +devlin;4887 +ladyhawke;4888 +ween;4889 +mates of state;4890 +husky rescue;4891 +rhett akins;4892 +godsmack;4893 +grandpa jones;4894 +matt maher;4895 +ill niño;4896 +flatfoot 56;4897 +josh garrels;4898 +obey the brave;4899 +damh the bard;4900 +sara lov;4901 +charles aznavour;4902 +thin lizzy;4903 +fatherson;4904 +tristania;4905 +binary star;4906 +warlock;4907 +ray j;4908 +jamie grace;4909 +mildred bailey;4910 +heartsrevolution;4911 +the dreaming;4912 +the feelies;4913 +lucy rose;4914 +artifacts;4915 +m (uk);4916 +the nits;4917 +the outfield;4918 +freelance whales;4919 +4minute;4920 +babyland;4921 +propagandhi;4922 +lil johnson;4923 +digital summer;4924 +the tenors;4925 +simply red;4926 +de-phazz;4927 +benny goodman;4928 +foxy brown;4929 +brainstorm;4930 +helen kane;4931 +les humphries singers;4932 +the prids;4933 +bruce cockburn;4934 +superbus;4935 +ben e. king;4936 +cryonic temple;4937 +renard;4938 +tom robinson;4939 +the cover girls;4940 +i, the breather;4941 +worm is green;4942 +commodores;4943 +julie doiron;4944 +portugal. the man;4945 +mike & the mechanics;4946 +7 year bitch;4947 +venetian snares;4948 +johnny mercer;4949 +grandaddy;4950 +malia;4951 +azure ray;4952 +carolina liar;4953 +nitronoise;4954 +rufus wainwright;4955 +the internet;4956 +j-zone;4957 +coronatus;4958 +celestial season;4959 +jimmy buffett;4960 +freeway;4961 +danielson;4962 +zwan;4963 +boys night out;4964 +julia jacklin;4965 +the fair sex;4966 +okkervil river;4967 +the raveonettes;4968 +wilson phillips;4969 +elane;4970 +andi deris;4971 +rocking chairs;4972 +michael johnson;4973 +rush;4974 +the oak ridge boys;4975 +rev. edward w. clayborn;4976 +bonnie bianco;4977 +ryan bingham;4978 +jeremy enigk;4979 +godhead;4980 +before their eyes;4981 +arsonists get all the girls;4982 +empyrium;4983 +bedlight for blue eyes;4984 +rehab;4985 +dead sara;4986 +snafu;4987 +roy acuff;4988 +the partridge family;4989 +malcolm holcombe;4990 +portastatic;4991 +thievery corporation;4992 +elysium;4993 +the other;4994 +beardfish;4995 +vanessa amorosi;4996 +babylon whores;4997 +pink floyd;4998 +nana grizol;4999 +charly mcclain;5000 +chico debarge;5001 +ten masked men;5002 +beloved;5003 +the shamen;5004 +charlie peacock;5005 +andr s schiff;5006 +castanets;5007 +cold cave;5008 +michael schenker group;5009 +house vs. hurricane;5010 +the pentangle;5011 +weerd science;5012 +ghost brigade;5013 +daysend;5014 +manfred mann's earth band;5015 +electrelane;5016 +smokin' joe kubek & bnois king;5017 +walter becker;5018 +el perro del mar;5019 +heaven & earth;5020 +amebix;5021 +stanfour;5022 +vallenfyre;5023 +tankard;5024 +circa waves;5025 +louis lortie;5026 +hammock;5027 +birdman;5028 +esther phillips;5029 +garnet rogers;5030 +icona pop;5031 +chvrches;5032 +donald fagen;5033 +kim mitchell;5034 +canibus;5035 +woods of ypres;5036 +four letter lie;5037 +eug ne ysa e;5038 +biz markie;5039 +tila tequila;5040 +blue mountain;5041 +buddy holly;5042 +rootwater;5043 +obie trice;5044 +ferlin husky;5045 +hinds;5046 +emmylou harris;5047 +hop along;5048 +ian moore;5049 +roger;5050 +micky & the motorcars;5051 +bebel gilberto;5052 +rod stewart;5053 +richard smallwood;5054 +deftones;5055 +suicide silence;5056 +the wrights;5057 +rudolf firku n ;5058 +god module;5059 +gregory alan isakov;5060 +angus & julia stone;5061 +real mccoy;5062 +kate miller-heidke;5063 +eric's trip;5064 +woe, is me;5065 +rex orange county;5066 +jascha heifetz;5067 +novembre;5068 +ministry;5069 +graveyard;5070 +tone damli;5071 +alien sex fiend;5072 +eazy-e;5073 +jj72;5074 +sublime;5075 +george formby;5076 +trapeze;5077 +mikhail pletnev;5078 +roger clyne & the peacemakers;5079 +rita coolidge;5080 +xxxtentacion;5081 +liz durrett;5082 +collective soul;5083 +second person;5084 +mat kearney;5085 +mr. 3-2;5086 +ezio;5087 +the republic of wolves;5088 +stepdad;5089 +mike oldfield;5090 +red sun rising;5091 +snfu;5092 +saul williams;5093 +justin townes earle;5094 +upon a burning body;5095 +bruce hungerford;5096 +jeff scott soto;5097 +big business;5098 +dan tyminski;5099 +infected mushroom;5100 +elend;5101 +john waite;5102 +hilary hahn;5103 +austin mahone;5104 +pretty girls make graves;5105 +billy idol;5106 +stephen malkmus;5107 +moddi;5108 +galahad;5109 +diana krall;5110 +the be good tanyas;5111 +!distain;5112 +the isley brothers;5113 +marilyn manson;5114 +blackthorn;5115 +ordinary time;5116 +dragonforce;5117 +i blame coco;5118 +this providence;5119 +t-pain;5120 +capleton;5121 +dc talk;5122 +leon redbone;5123 +optimus rhyme;5124 +zedd;5125 +black label society;5126 +gary brooker;5127 +melvins;5128 +mindless faith;5129 +the warning;5130 +bombshell rocks;5131 +the unthanks;5132 +secrets;5133 +joan jett and the blackhearts;5134 +funeral for a friend;5135 +aorta;5136 +roger glover;5137 +nitzer ebb;5138 +amber pacific;5139 +sneaker pimps;5140 +insomnium;5141 +danger radio;5142 +lay low;5143 +russ;5144 +bliss n eso;5145 +dj antoine;5146 +to kill a king;5147 +dubstar;5148 +by the tree;5149 +imelda may;5150 +emil gilels;5151 +redbone;5152 +the highwaymen;5153 +fear;5154 +ry cooder;5155 +ludo;5156 +mance lipscomb;5157 +shawn colvin;5158 +bongzilla;5159 +the promise ring;5160 +dr. dog;5161 +ronnie dunn;5162 +the buffoons;5163 +aimee mann;5164 +chase & status;5165 +rose maddox;5166 +lights;5167 +akissforjersey;5168 +tommy shaw;5169 +rotersand;5170 +x japan;5171 +richie furay;5172 +provision;5173 +gordon lightfoot;5174 +primus;5175 +die sektor;5176 +megadeth;5177 +agnetha fältskog;5178 +angelspit;5179 +machine gun kelly;5180 +father;5181 +cherry ghost;5182 +nana;5183 +ensign;5184 +björk;5185 +styx;5186 +cinema bizarre;5187 +tiamat;5188 +chris mills;5189 +rachael sage;5190 +prāta vētra;5191 +the hold steady;5192 +phil lynott;5193 +brian hyland;5194 +we as human;5195 +the wallflowers;5196 +kalan porter;5197 +freddie hart;5198 +corey crowder;5199 +the angels of light;5200 +papermoon;5201 +tommy mcclennan;5202 +the paper chase;5203 +ikon;5204 +happy monster band;5205 +modern talking;5206 +philadelphia orchestra;5207 +hellyeah;5208 +heart of a coward;5209 +state property;5210 +howling bells;5211 +shalamar;5212 +the geraldine fibbers;5213 +toots & the maytals;5214 +walter trout;5215 +michael o'brien;5216 +sweet;5217 +hate eternal;5218 +carnival in coal;5219 +céline dion;5220 +lee hazlewood;5221 +amy holland;5222 +defleshed;5223 +irma thomas;5224 +the chieftains;5225 +dexter freebish;5226 +the lads;5227 +peter bradley adams;5228 +front line assembly;5229 +blindside;5230 +vulfpeck;5231 +kontrust;5232 +smosh;5233 +boy & bear;5234 +cruachan;5235 +berried alive;5236 +the raconteurs;5237 +dälek;5238 +julie andrews;5239 +spoon;5240 +mad caddies;5241 +she keeps bees;5242 +martha tilston;5243 +le butcherettes;5244 +the vines;5245 +mothers;5246 +biohazard;5247 +doug macleod;5248 +down;5249 +maestro fresh-wes;5250 +boston;5251 +oh susanna;5252 +goldfrapp;5253 +sons of bill;5254 +fun people;5255 +the crown;5256 +tim maia;5257 +sevdaliza;5258 +the little willies;5259 +cupcakke;5260 +poxy boggards;5261 +damon intrabartolo;5262 +mostly autumn;5263 +jim reeves;5264 +dir en grey;5265 +robin beck;5266 +the sounds;5267 +migos;5268 +de/vision;5269 +larry santos;5270 +combichrist;5271 +milla jovovich;5272 +luba;5273 +sharon van etten;5274 +forevermore;5275 +roger daltrey;5276 +lunik;5277 +maroon;5278 +the rolling stones;5279 +jon secada;5280 +yehudi menuhin;5281 +stompin' tom connors;5282 +r.l. burnside;5283 +a tortured soul;5284 +con hunley;5285 +the supernaturals;5286 +the kooks;5287 +jeff beck;5288 +pokey lafarge;5289 +watermark;5290 +au revoir simone;5291 +matthew barber;5292 +u-god;5293 +blaze bayley;5294 +haste the day;5295 +chase rice;5296 +ariana grande;5297 +bukka white;5298 +skew siskin;5299 +monster magnet;5300 +the oh hellos;5301 +the pop group;5302 +haim;5303 +bay city rollers;5304 +mustasch;5305 +mc magic;5306 +sherbet;5307 +the tea party;5308 +the choir;5309 +woody guthrie;5310 +hypocrisy;5311 +big maceo;5312 +the psychedelic furs;5313 +ariel pink;5314 +fourplay;5315 +paw;5316 +beirut;5317 +french kicks;5318 +the ronettes;5319 +the durutti column;5320 +therefore i am;5321 +d-a-d;5322 +eric martin;5323 +andrea schroeder;5324 +john hiatt;5325 +incantation;5326 +lisa marie presley;5327 +high and mighty color;5328 +vonda shepard;5329 +asphyx;5330 +israel vibration;5331 +lordi;5332 +nikki yanofsky;5333 +the box tops;5334 +jorma kaukonen;5335 +juice newton;5336 +woody's a girl;5337 +matthew logan vasquez;5338 +aretha franklin;5339 +buddy miller;5340 +ayreon;5341 +mediæval bæbes;5342 +accept;5343 +robert schuman;5344 +mina;5345 +will.i.am;5346 +marc almond;5347 +nomeansno;5348 +defeater;5349 +suggs;5350 +grobschnitt;5351 +amon düül ii;5352 +feeling left out;5353 +breaking benjamin;5354 +george michael;5355 +bracket;5356 +all-4-one;5357 +niccol paganini;5358 +la coka nostra;5359 +ozzy osbourne;5360 +the bobs;5361 +jay reatard;5362 +satellites;5363 +gwen stacy;5364 +soulspell;5365 +anchor;5366 +girls' generation;5367 +lacy j. dalton;5368 +lil mama;5369 +florrie;5370 +lesley gore;5371 +sara k.;5372 +upon this dawning;5373 +barry adamson;5374 +christine and the queens;5375 +timbaland;5376 +pj morton;5377 +the divine comedy;5378 +bascom lamar lunsford;5379 +cilla black;5380 +spank rock;5381 +jeff healey;5382 +molotov solution;5383 +matthew fisher;5384 +francis poulenc;5385 +anata;5386 +sara watkins;5387 +amy macdonald;5388 +coldworker;5389 +london symphony;5390 +danny brown;5391 +kandi;5392 +bic runga;5393 +iggy pop;5394 +die toten hosen;5395 +tuck & patti;5396 +richard goode;5397 +blind boy fuller;5398 +sonny & cher;5399 +jeremih;5400 +spiritual front;5401 +d'espairsray;5402 +shirley bassey;5403 +annuals;5404 +bros;5405 +charlotte martin;5406 +ramones;5407 +paper route;5408 +cretin;5409 +streetwalkers;5410 +number one gun;5411 +the smithereens;5412 +belvedere;5413 +tech n9ne;5414 +corinne bailey rae;5415 +dawn of ashes;5416 +into eternity;5417 +corb lund;5418 +faz l say;5419 +current swell;5420 +albert collins;5421 +lita ford;5422 +rudimental;5423 +nightmare of you;5424 +josef lh vinne;5425 +stephen bishop;5426 +richie kotzen;5427 +run-d.m.c.;5428 +the moody blues;5429 +divinyls;5430 +good old war;5431 +anders johansson;5432 +gandalf's fist;5433 +baccara;5434 +miniature tigers;5435 +rare earth;5436 +the walker brothers;5437 +molly johnson;5438 +we five;5439 +the verve pipe;5440 +the foreshadowing;5441 +sam the sham & the pharaohs;5442 +fifth harmony;5443 +madonna;5444 +juluka;5445 +dynazty;5446 +michael schulte;5447 +thompson twins;5448 +lil wyte;5449 +mike batt;5450 +trial;5451 +cisco houston;5452 +callisto;5453 +darkest hour;5454 +brian may;5455 +david wilcox;5456 +napalm death;5457 +never heard of it;5458 +jj grey & mofro;5459 +eric andersen;5460 +billie piper;5461 +chromeo;5462 +youri egorov;5463 +aaron lewis;5464 +vince neil;5465 +buddy guy & junior wells;5466 +róisín murphy;5467 +in the woods...;5468 +aesma daeva;5469 +electric guest;5470 +murray mclauchlan;5471 +thee oh sees;5472 +nick kamen;5473 +eloy;5474 +brian eno;5475 +rabbit junk;5476 +suidakra;5477 +mint condition;5478 +extreme;5479 +kelley stoltz;5480 +mattafix;5481 +tiara thomas;5482 +fugees;5483 +warpaint;5484 +selena gomez & the scene;5485 +hot boy$;5486 +allen toussaint;5487 +skrillex;5488 +john schneider;5489 +midlake;5490 +the supremes;5491 +rodney crowell;5492 +everyone everywhere;5493 +theatre of tragedy;5494 +s.f.a.;5495 +dreamtale;5496 +count bass d;5497 +ivy sole;5498 +bobby blue bland;5499 +popcaan;5500 +tab benoit;5501 +grinspoon;5502 +grizzly bear;5503 +kirk franklin;5504 +grateful dead;5505 +21 guns;5506 +scouting for girls;5507 +fay lovsky;5508 +the fullblast;5509 +death;5510 +the elected;5511 +transvision vamp;5512 +keith urban;5513 +left spine down;5514 +the nylons;5515 +alien ant farm;5516 +otep;5517 +ashton shepherd;5518 +paradise lost;5519 +hello saferide;5520 +john kay;5521 +the beach boys;5522 +gregory porter;5523 +ricky martin;5524 +wayne hancock;5525 +youn sun nah;5526 +winger;5527 +havoc;5528 +los campesinos!;5529 +shaun cassidy;5530 +chevelle;5531 +barbara mason;5532 +rita wilson;5533 +richie havens;5534 +scythe;5535 +d.r.i.;5536 +matt andersen;5537 +fifth angel;5538 +trail of tears;5539 +asaf avidan & the mojos;5540 +christopher lee;5541 +tripod;5542 +crywank;5543 +tank;5544 +tom paxton;5545 +leon russell;5546 +adam green;5547 +anarbor;5548 +the unicorns;5549 +evidence;5550 +stetsasonic;5551 +the gabe dixon band;5552 +prince;5553 +day26;5554 +rhythms del mundo;5555 +saviour machine;5556 +alina simone;5557 +dick haymes;5558 +hugh laurie;5559 +jc chasez;5560 +johnny clegg & savuka;5561 +rivers of nihil;5562 +overkill;5563 +guy;5564 +memphis slim & willie dixon;5565 +jocelyn & chris arndt;5566 +mechanical moth;5567 +pat benatar;5568 +eden's curse;5569 +gene pitney;5570 +rodriguez;5571 +jamala;5572 +jerry garcia band;5573 +demon;5574 +backstreet boys;5575 +cocorosie;5576 +savatage;5577 +rosemary clooney;5578 +amerie;5579 +ian dury and the blockheads;5580 +pantokrator;5581 +the lox;5582 +supertramp;5583 +carnal forge;5584 +this is hell;5585 +papooz;5586 +julia holter;5587 +traffic;5588 +gary lewis & the playboys;5589 +leopold godowsky;5590 +inferi;5591 +remembering never;5592 +the radio dept.;5593 +blind willie johnson;5594 +gary chapman;5595 +mutual benefit;5596 +dragonette;5597 +crooked fingers;5598 +black mountain;5599 +shampoo;5600 +onslaught;5601 +big moe;5602 +the tragically hip;5603 +dead by april;5604 +john parr;5605 +chameleon circuit;5606 +all;5607 +greeley estates;5608 +herbie hancock;5609 +karmakanic;5610 +coffin break;5611 +blood orange;5612 +alborosie;5613 +aeternus;5614 +rich boy;5615 +cledus t. judd;5616 +bobby brown;5617 +zebra;5618 +scott matthew;5619 +winter's bane;5620 +kane & abel;5621 +jackson c. frank;5622 +maura o'connell;5623 +color me badd;5624 +christina aguilera;5625 +3rd bass;5626 +danny gokey;5627 +galactic cowboys;5628 +sabaton;5629 +howard jones;5630 +s.p.o.c.k;5631 +heather alexander;5632 +ingested;5633 +terror jr;5634 +enuff z'nuff;5635 +the gothic archies;5636 +robert ellis;5637 +nancy wilson;5638 +dead kennedys;5639 +milow;5640 +hall & oates;5641 +the mynabirds;5642 +grass widow;5643 +mew;5644 +chris young;5645 +crest of darkness;5646 +b.j. thomas;5647 +sister sledge;5648 +john lee hooker and canned heat;5649 +screeching weasel;5650 +cassandra wilson;5651 +terry reid;5652 +maps;5653 +katy perry;5654 +swmrs;5655 +neurotech;5656 +george gershwin;5657 +april wine;5658 +powerwolf;5659 +yellowcard;5660 +the kry;5661 +barbarossa;5662 +blackguard;5663 +rjd2;5664 +angelo de augustine;5665 +brand nubian;5666 +iron reagan;5667 +snap!;5668 +the expos;5669 +paula abdul;5670 +bahamas;5671 +olive;5672 +gene simmons;5673 +augustana;5674 +vicious crusade;5675 +mennen;5676 +arsonists;5677 +fred penner;5678 +amen;5679 +mae;5680 +the stylistics;5681 +bill monroe;5682 +aeon zen;5683 +paul williams;5684 +ultraviolet sound;5685 +omnia;5686 +dave cousins;5687 +silent stream of godless elegy;5688 +david lindley;5689 +title fight;5690 +stevie nicks;5691 +disturbed;5692 +the lumineers;5693 +wondermints;5694 +necromantia;5695 +anton bruckner;5696 +john hammond;5697 +counterparts;5698 +the pursuit of happiness;5699 +dougie maclean;5700 +domo genesis;5701 +keaton henson;5702 +the electric hellfire club;5703 +casting crowns;5704 +her space holiday;5705 +lindi ortega;5706 +toy dolls;5707 +kobra and the lotus;5708 +velvet acid christ;5709 +hafdís huld;5710 +dead infection;5711 +blues traveler;5712 +hawthorne heights;5713 +emf;5714 +the secret handshake;5715 +einstürzende neubauten;5716 +rednex;5717 +aztec camera;5718 +heart in hand;5719 +easyworld;5720 +shlomo mintz;5721 +earl wild;5722 +french montana;5723 +prime sth;5724 +craig david;5725 +blind pilot;5726 +stratovarius;5727 +nina nesbitt;5728 +fiddler's green;5729 +skyclad;5730 +caitlyn smith;5731 +daniel lavoie;5732 +diamond rio;5733 +the four lads;5734 +die warzau;5735 +funker vogt;5736 +black tusk;5737 +bob seger;5738 +labyrinth;5739 +teodasia;5740 +magnapop;5741 +dødheimsgard;5742 +barrio boyzz;5743 +jesse malin;5744 +the brothers johnson;5745 +the obsessed;5746 +lucky boys confusion;5747 +lemon jelly;5748 +cock sparrer;5749 +itzhak perlman;5750 +amberian dawn;5751 +moxy früvous;5752 +ugress;5753 +the thermals;5754 +common;5755 +torres;5756 +badlands;5757 +ron kenoly;5758 +wide mouth mason;5759 +run kid run;5760 +qntal;5761 +patty larkin;5762 +the answer;5763 +la bouche;5764 +abba;5765 +melanie thornton;5766 +limp bizkit;5767 +danny wilde;5768 +against all authority;5769 +志方あきこ;5770 +a plea for purging;5771 +chris caffery;5772 +7l & esoteric;5773 +jagged edge;5774 +allo darlin';5775 +domenico scarlatti;5776 +b-legit;5777 +hundreds;5778 +jonathan richman and the modern lovers;5779 +catharsis;5780 +son volt;5781 +electric valentine;5782 +gino vannelli;5783 +call the cops;5784 +miss may i;5785 +double you;5786 +the soul stirrers;5787 +adrenaline mob;5788 +timothy seth avett as darling;5789 +raging fyah;5790 +ナイトメア (nightmare);5791 +selena gomez;5792 +franco battiato;5793 +sons of seasons;5794 +aaron shust;5795 +august alsina;5796 +ghoul;5797 +mustard plug;5798 +the white stripes;5799 +dead stop;5800 +slim;5801 +project 86;5802 +lower dens;5803 +stephen fretwell;5804 +off!;5805 +psychostick;5806 +radney foster;5807 +black uhuru;5808 +one without;5809 +the presidents of the united states of america;5810 +phil ochs;5811 +stealers wheel;5812 +the angels;5813 +joy williams;5814 +nick jonas;5815 +owl city;5816 +the gourds;5817 +cowboy junkies;5818 +cru;5819 +the rembrandts;5820 +useless id;5821 +jessica andrews;5822 +big black;5823 +my brightest diamond;5824 +johnny kidd & the pirates;5825 +moonface;5826 +angra;5827 +john mccutcheon;5828 +sharon jones & the dap-kings;5829 +brother dege;5830 +john p. kee;5831 +armin van buuren;5832 +houndmouth;5833 +the spencer davis group;5834 +poison idea;5835 +carach angren;5836 +the horrors;5837 +johnny paycheck;5838 +primal fear;5839 +joanna newsom;5840 +weezer;5841 +bluehorses;5842 +architecture in helsinki;5843 +steve mcconnell;5844 +townes van zandt;5845 +johnny cash & june carter cash;5846 +dust of basement;5847 +j dilla;5848 +too pure to die;5849 +car seat headrest;5850 +rita springer;5851 +max romeo;5852 +calabrese;5853 +trey anastasio;5854 +young thug;5855 +harry and the potters;5856 +clifford t. ward;5857 +confederate railroad;5858 +ice mc;5859 +tyler shaw;5860 +will smith;5861 +anna tivel;5862 +the pierces;5863 +sabbat;5864 +papercuts;5865 +trouble over tokyo;5866 +a storm of light;5867 +earl scruggs;5868 +limahl;5869 +band of horses;5870 +suspyre;5871 +shy girls;5872 +blood;5873 +madness;5874 +georgie fame;5875 +glass tiger;5876 +50 cent;5877 +mike doughty;5878 +y-o-u;5879 +ass ponys;5880 +mary gauthier;5881 +goldfinger;5882 +delbert mcclinton;5883 +freak kitchen;5884 +lalaine;5885 +destiny's child;5886 +thirsty merc;5887 +daniel bedingfield;5888 +armored saint;5889 +¡mayday!;5890 +cheryl cole;5891 +richie spice;5892 +luscious jackson;5893 +altan;5894 +evanescence;5895 +luther vandross;5896 +steve wariner;5897 +deadlock;5898 +brenda lee;5899 +noe venable;5900 +korn;5901 +the letter black;5902 +star fucking hipsters;5903 +daniel o'donnell;5904 +theatres des vampires;5905 +the dogma;5906 +ria mae;5907 +thy art is murder;5908 +mali music;5909 +eydie gorme;5910 +housefires;5911 +brooks & dunn;5912 +million dead;5913 +kurt vile;5914 +3lw;5915 +helix;5916 +judy collins;5917 +albert hammond;5918 +coroner;5919 +red flag;5920 +ralph vaughan williams;5921 +infected rain;5922 +ann wilson;5923 +anthony evans;5924 +christina milian;5925 +taco;5926 +lee greenwood;5927 +jon anderson;5928 +bun b;5929 +skye sweetnam;5930 +britney spears;5931 +peter serkin;5932 +saywecanfly;5933 +gordon haskell;5934 +grouplove;5935 +walter egan;5936 +malinky;5937 +mandy barnett;5938 +mystery skulls;5939 +jeremy larson;5940 +charley patton;5941 +modern english;5942 +inhale exhale;5943 +avantasia;5944 +huntingtons;5945 +shudder to think;5946 +the brand new heavies;5947 +slice the cake;5948 +sick of sarah;5949 +winds;5950 +the rakes;5951 +ray lamontagne;5952 +haircut 100;5953 +your demise;5954 +exposé;5955 +narada michael walden;5956 +lord of the lost;5957 +the rubettes;5958 +aloe blacc;5959 +jeff wayne;5960 +in this moment;5961 +the move;5962 +machine men;5963 +orenda fink;5964 +tina dico;5965 +ziggy marley & the melody makers;5966 +noël coward;5967 +bonfire;5968 +hawkwind;5969 +jessie j;5970 +emitt rhodes;5971 +john martyn;5972 +blue öyster cult;5973 +the silver shine;5974 +tex ritter;5975 +kishi bashi;5976 +sonny james;5977 +mind's eye;5978 +the sleeping;5979 +the derek trucks band;5980 +atmosphere;5981 +lauren daigle;5982 +taj weekes & adowa;5983 +ricky skaggs;5984 +alabama shakes;5985 +black star;5986 +gong;5987 +viper;5988 +fruit bats;5989 +allie x;5990 +josh woodward;5991 +kungfu rick;5992 +the weavers;5993 +blood, sweat & tears;5994 +the stooges;5995 +the white birch;5996 +john mayall;5997 +diamond d;5998 +luigi boccherini;5999 +half man half biscuit;6000 +ralph mctell;6001 +lisa brokop;6002 +son lux;6003 +wumpscut;6004 +beneath the massacre;6005 +nine inch nails;6006 +ancient rites;6007 +drop dead, gorgeous;6008 +no mercy;6009 +lene lovich;6010 +widowmaker;6011 +the microphones;6012 +rita connolly;6013 +generation x;6014 +assassin;6015 +horse feathers;6016 +lola monroe;6017 +bette midler;6018 +gentleman;6019 +the crystal method;6020 +crystal bernard;6021 +black 47;6022 +starbenders;6023 +landmine marathon;6024 +múm;6025 +califone;6026 +allister;6027 +for all those sleeping;6028 +fgfc820;6029 +anner bylsma;6030 +lilys;6031 +triptykon;6032 +danger doom;6033 +big k.r.i.t.;6034 +assemblage 23;6035 +howie day;6036 +miike snow;6037 +diiv;6038 +the rapture;6039 +the civil wars;6040 +liege lord;6041 +nicolette larson;6042 +slayer;6043 +2pac;6044 +16;6045 +grigory sokolov;6046 +martin carthy;6047 +bowerbirds;6048 +ginger;6049 +luka bloom;6050 +young jeezy;6051 +kate rusby;6052 +the pretty things;6053 +2 chainz;6054 +man overboard;6055 +paul tortelier;6056 +doyle lawson & quicksilver;6057 +timber timbre;6058 +johnny rodriguez;6059 +and one;6060 +grand funk railroad;6061 +kiss;6062 +elysian fields;6063 +ace enders & a million different people;6064 +hoods;6065 +frenzal rhomb;6066 +army of freshmen;6067 +unter null;6068 +frankie lee sims;6069 +joe;6070 +sahara hotnights;6071 +alison moyet;6072 +janis ian;6073 +delinquent habits;6074 +heffron drive;6075 +jackie wilson;6076 +osi;6077 +mobb deep;6078 +corey cerovsek;6079 +pras;6080 +buckcherry;6081 +dave davies;6082 +beto vázquez infinity;6083 +drowning the light;6084 +attack attack!;6085 +day of fire;6086 +ida haendel;6087 +ytcracker;6088 +u2;6089 +stan freberg;6090 +saint lu;6091 +jj;6092 +robert bradley's blackwater surprise;6093 +pharrell williams;6094 +no trend;6095 +darkwell;6096 +van dyke parks;6097 +cannonball statman;6098 +thursday;6099 +kathleen edwards;6100 +sentenced;6101 +crown the empire;6102 +crimson thorn;6103 +george benson;6104 +the concretes;6105 +kahimi karie;6106 +jimi hendrix;6107 +dock boggs;6108 +tom vek;6109 +(spunge);6110 +the refreshments;6111 +twilightning;6112 +the-dream;6113 +portishead;6114 +eamon;6115 +soulfly;6116 +gungor;6117 +stemm;6118 +mc hammer;6119 +the kinks;6120 +budgie;6121 +pistol annies;6122 +froggy fresh;6123 +shaye;6124 +tlc;6125 +the chameleons;6126 +boss hogg outlawz;6127 +starbomb;6128 +sleigh bells;6129 +inquisition;6130 +h-blockx;6131 +the ting tings;6132 +johnny hallyday;6133 +night ranger;6134 +bowes & morley;6135 +ronan keating;6136 +d'sound;6137 +miki howard;6138 +sadat x;6139 +gloria estefan;6140 +mighty sparrow;6141 +the shins;6142 +starfield;6143 +plan b;6144 +marcus orelias;6145 +neaera;6146 +miss black america;6147 +arena;6148 +assück;6149 +a. l. lloyd;6150 +los lobos;6151 +artur schnabel;6152 +boyce avenue;6153 +chixdiggit!;6154 +stevie wonder;6155 +howlin rain;6156 +junior wells;6157 +con funk shun;6158 +nickel creek;6159 +there for tomorrow;6160 +brian peters;6161 +mgmt;6162 +his name is alive;6163 +jaya the cat;6164 +chiodos;6165 +teacup monster;6166 +har mar superstar;6167 +alkaline trio;6168 +kidz bop;6169 +baxter;6170 +scary bitches;6171 +ron wood;6172 +dashboard confessional;6173 +iron fire;6174 +shimshai;6175 +carl maria von weber;6176 +aversions crown;6177 +apartment 26;6178 +alcazar;6179 +skeleton key;6180 +the burning hell;6181 +bonded by blood;6182 +bob marley & the wailers;6183 +spirit;6184 +the jackson 5;6185 +george morgan;6186 +alabama 3;6187 +the sensational alex harvey band;6188 +drapht;6189 +nevertheless;6190 +china crisis;6191 +selena;6192 +bodies of water;6193 +crush 40;6194 +architects;6195 +darius rucker;6196 +smile.dk;6197 +puhdys;6198 +savoy brown;6199 +rose royce;6200 +plumb;6201 +roger waters;6202 +doc watson;6203 +neal morse;6204 +edwin fischer;6205 +tracy chapman;6206 +the who;6207 +cal smith;6208 +mos def;6209 +matt cardle;6210 +dr. dre;6211 +ronnie milsap;6212 +anthrax;6213 +tw walsh;6214 +numb;6215 +jenny o.;6216 +lock up;6217 +bear in heaven;6218 +susanna hoffs;6219 +jessie ware;6220 +eric bogle;6221 +johnny thunders;6222 +advance base;6223 +sara gazarek;6224 +misfits;6225 +the used;6226 +catie curtis;6227 +thundercat;6228 +derek minor;6229 +basshunter;6230 +johann pachelbel;6231 +whitehorse;6232 +bessie smith;6233 +mike garrigan;6234 +brownie mcghee;6235 +otis rush;6236 +negative;6237 +slugdge;6238 +bang gang;6239 +debbie gibson;6240 +da vinci's notebook;6241 +nargaroth;6242 +champion jack dupree;6243 +hubert kah;6244 +ben lee;6245 +gary barlow;6246 +math and physics club;6247 +eighteen visions;6248 +supersuckers;6249 +the fixx;6250 +amazing blondel;6251 +morcheeba;6252 +petula clark;6253 +the youngbloods;6254 +carman;6255 +southern culture on the skids;6256 +evan taubenfeld;6257 +tracy grammer;6258 +maritime;6259 +randy vanwarmer;6260 +believer;6261 +the grapes of wrath;6262 +angelina;6263 +john prine;6264 +dee snider;6265 +jon and vangelis;6266 +the seer;6267 +george jones;6268 +amanda perez;6269 +lonnie donegan;6270 +lara fabian;6271 +dr. acula;6272 +cockney rejects;6273 +junkie xl;6274 +nasty c;6275 +the shadows;6276 +this beautiful republic;6277 +12 rods;6278 +action action;6279 +jann arden;6280 +the oppressed;6281 +emanuel;6282 +jennifer rush;6283 +ufo;6284 +leroy anderson;6285 +the submarines;6286 +vanilla ice;6287 +the murder city devils;6288 +johnny mathis;6289 +michael card;6290 +rheostatics;6291 +no knife;6292 +curved air;6293 +mu330;6294 +bat for lashes;6295 +abigor;6296 +new boyz;6297 +nb ridaz;6298 +brian mcfadden;6299 +kylesa;6300 +randy bachman;6301 +brandon heath;6302 +the adicts;6303 +longwave;6304 +earl thomas conley;6305 +lethian dreams;6306 +conchita wurst;6307 +southgang;6308 +david oistrakh;6309 +a change of pace;6310 +it lives, it breathes;6311 +the format;6312 +enrico caruso;6313 +ron hawkins;6314 +sufjan stevens;6315 +krystian zimerman;6316 +it prevails;6317 +redrama;6318 +warcloud;6319 +the kids from fame;6320 +brodka;6321 +nujabes;6322 +bt;6323 +voltaire;6324 +one be lo;6325 +damon & naomi;6326 +datarock;6327 +willow smith;6328 +snowy white;6329 +mercyful fate;6330 +veruca salt;6331 +joe bonamassa;6332 +rag'n'bone man;6333 +aqualung;6334 +solomon burke;6335 +vicious rumors;6336 +spitalfield;6337 +hardcore superstar;6338 +vern gosdin;6339 +yendri;6340 +pernice brothers;6341 +vangough;6342 +t-bone;6343 +sopor aeternus;6344 +day at the fair;6345 +feed her to the sharks;6346 +dokken;6347 +teena marie;6348 +json;6349 +kaipa;6350 +hidden in plain view;6351 +belinda carlisle;6352 +neil cicierega;6353 +brenda russell;6354 +esther ofarim;6355 +sea wolf;6356 +fm laeti;6357 +james hunter;6358 +the soul of john black;6359 +david bromberg;6360 +marc cohn;6361 +the duskfall;6362 +galantis;6363 +tender;6364 +martin jondo;6365 +ricky nelson;6366 +jeremy spencer;6367 +colin linden;6368 +john cooper clarke;6369 +the seekers;6370 +abra moore;6371 +breathe carolina;6372 +lily & madeleine;6373 +disarmonia mundi;6374 +circa survive;6375 +matt bianco;6376 +celtic thunder;6377 +flowing tears;6378 +lee fields;6379 +kate ryan;6380 +meg & dia;6381 +evils toy;6382 +choirboys;6383 +tedashii;6384 +poni hoax;6385 +yo yo ma;6386 +the broken family band;6387 +l'âme immortelle;6388 +psalters;6389 +benjamin britten;6390 +shakira;6391 +rabia sorda;6392 +ad;6393 +the cross;6394 +billy boy arnold;6395 +florida georgia line;6396 +t.i.;6397 +marty willson-piper;6398 +client;6399 +jack ingram;6400 +sash!;6401 +deathstars;6402 +the english beat;6403 +mitchel musso;6404 +wintersleep;6405 +the smiths;6406 +fleetwood mac;6407 +molly hatchet;6408 +pet shop boys;6409 +daryl hall;6410 +after all;6411 +j moss;6412 +rüfüs du sol;6413 +exodus;6414 +francis dunnery;6415 +4 strings;6416 +heather headley;6417 +besatt;6418 +foreigner;6419 +the pussycat dolls;6420 +serena ryder;6421 +white lion;6422 +tim hardin;6423 +harry connick, jr.;6424 +islands;6425 +arrested development;6426 +coco montoya;6427 +arcana;6428 +marduk;6429 +keith whitley;6430 +al martino;6431 +scatman john;6432 +marvin gaye & tammi terrell;6433 +eddie murphy;6434 +rihanna;6435 +candi staton;6436 +my favorite;6437 +the trews;6438 +coven 13;6439 +leo sayer;6440 +lil' keke;6441 +jewel;6442 +firehouse;6443 +claudio monteverdi;6444 +negative approach;6445 +ben caplan;6446 +aïboforcen;6447 +ryan shupe & the rubberband;6448 +bethel music;6449 +the courteeners;6450 +mortal love;6451 +yung lean;6452 +altar boys;6453 +aesop rock;6454 +bret michaels;6455 +die so fluid;6456 +don mclean;6457 +my morning jacket;6458 +unearthly trance;6459 +the war on drugs;6460 +limp;6461 +drake bell;6462 +cky;6463 +b.b. king;6464 +mama cass;6465 +dirty heads;6466 +buffy sainte-marie;6467 +dire straits;6468 +menudo;6469 +dolorian;6470 +natalie imbruglia;6471 +flunk;6472 +carpark north;6473 +fatso jetson;6474 +hourglass;6475 +graveland;6476 +bert jansch;6477 +the left banke;6478 +the sound;6479 +nancy lamott;6480 +the mighty mighty bosstones;6481 +lake of tears;6482 +paper aeroplanes;6483 +the archies;6484 +the wonder years;6485 +con brio;6486 +the treatment;6487 +fats domino;6488 +heaven shall burn;6489 +the suburbs;6490 +laura gibson;6491 +an angle;6492 +hunters & collectors;6493 +jellyfish;6494 +jim capaldi;6495 +hybrid;6496 +five for fighting;6497 +kevin fowler;6498 +douwe bob;6499 +george nozuka;6500 +american head charge;6501 +roots manuva;6502 +cephalic carnage;6503 +prodigy;6504 +far east movement;6505 +the spinners;6506 +plankeye;6507 +pitbull;6508 +reggie and the full effect;6509 +frightened rabbit;6510 +i see stars;6511 +lorde;6512 +vanessa williams;6513 +oh land;6514 +luciano;6515 +shockwave;6516 +i set my friends on fire;6517 +eagles of death metal;6518 +above & beyond;6519 +mindless self indulgence;6520 +sun kil moon;6521 +strawbs;6522 +vision divine;6523 +julien-k;6524 +the velvet teen;6525 +jack greene;6526 +devo;6527 +caesar;6528 +ritchie valens;6529 +andr previn;6530 +116 clique;6531 +ali project;6532 +leæther strip;6533 +take that;6534 +five iron frenzy;6535 +eugenio finardi;6536 +star one;6537 +barbara mandrell;6538 +to speak of wolves;6539 +massive ego;6540 +my ticket home;6541 +the riverboat gamblers;6542 +epic rap battles of history;6543 +revolver;6544 +waltari;6545 +k. michelle;6546 +natural;6547 +madder mortem;6548 +crystal gayle;6549 +yoko ono;6550 +robbie fulks;6551 +xandria;6552 +beyoncé;6553 +beth hirsch;6554 +passion pit;6555 +magnum;6556 +william beckett;6557 +the beautiful south;6558 +shakin' stevens;6559 +samantha fox;6560 +england dan & john ford coley;6561 +orchestral manoeuvres in the dark;6562 +chrom;6563 +deana carter;6564 +dan seals;6565 +crimson moonlight;6566 +alvin lee;6567 +army of lovers;6568 +the friday night boys;6569 +chris august;6570 +stephen lynch;6571 +loudon wainwright iii;6572 +the helio sequence;6573 +partynextdoor;6574 +roberta flack;6575 +mr. bungle;6576 +sóley;6577 +bruce springsteen;6578 +dmitry bashkirov;6579 +billy preston;6580 +department of eagles;6581 +denison witmer;6582 +modest petrovich mussorgsky;6583 +antonio meneses;6584 +kathryn williams;6585 +jim ed brown;6586 +arabesque;6587 +m83;6588 +johann strauss ii;6589 +agnes;6590 +alannah myles;6591 +most precious blood;6592 +incubus;6593 +rialto;6594 +a.c.t;6595 +klone;6596 +jp cooper;6597 +hate dept.;6598 +anderson .paak;6599 +viva voce;6600 +talisco;6601 +survivor;6602 +the manhattan transfer;6603 +van cliburn;6604 +maylene and the sons of disaster;6605 +brendan perry;6606 +derek and the dominos;6607 +kovacs;6608 +the association;6609 +fischer-z;6610 +fred neil;6611 +letlive;6612 +aberfeldy;6613 +onyx;6614 +dig;6615 +smokie;6616 +gabriel brown;6617 +jakob dylan;6618 +imogen heap;6619 +lacrosse;6620 +the kovenant;6621 +lotte kestner;6622 +das pop;6623 +andreya triana;6624 +the delmore brothers;6625 +talking heads;6626 +ty england;6627 +we are the in crowd;6628 +nick drake;6629 +dead or alive;6630 +jessica harp;6631 +deathgaze;6632 +more machine than man;6633 +rage;6634 +kim churchill;6635 +5 chinese brothers;6636 +emperor;6637 +the mavericks;6638 +aloha;6639 +999;6640 +leonard cohen;6641 +gabrielle aplin;6642 +living sacrifice;6643 +matt mays;6644 +too bad eugene;6645 +crystal fighters;6646 +harlan howard;6647 +wendy matthews;6648 +danny kirwan;6649 +john barrowman;6650 +those dancing days;6651 +thor;6652 +digger;6653 +steve earle;6654 +penal colony;6655 +davey suicide;6656 +rise against;6657 +iron maiden;6658 +world party;6659 +daforce;6660 +the monkees;6661 +yukmouth;6662 +demolition hammer;6663 +edguy;6664 +winds of plague;6665 +flatsound;6666 +james "j.t." taylor;6667 +dave alvin;6668 +dimmu borgir;6669 +kreator;6670 +pop etc;6671 +c.w. mccall;6672 +green river ordinance;6673 +dave dudley;6674 +steely dan;6675 +murderdolls;6676 +de la soul;6677 +the dayton family;6678 +transatlantic;6679 +neneh cherry;6680 +pete townshend;6681 +the red jumpsuit apparatus;6682 +abandon all ships;6683 +john brown's body;6684 +karl wolf;6685 +los pericos;6686 +this mortal coil;6687 +emily haines;6688 +pretenders;6689 +boytronic;6690 +bloodgood;6691 +unit;6692 +boyzone;6693 +ian & sylvia;6694 +jesse harris & the ferdinandos;6695 +haley reinhart;6696 +sinergy;6697 +gareth gates;6698 +kevin lyttle;6699 +cast;6700 +britny fox;6701 +jack jones;6702 +billy joel;6703 +the maine;6704 +david bazan;6705 +hate;6706 +intwine;6707 +pigface;6708 +lali puna;6709 +david usher;6710 +the shirelles;6711 +gerald moore;6712 +nicole dollanganger;6713 +rex goudie;6714 +pablo casals;6715 +the veils;6716 +low pop suicide;6717 +graham colton;6718 +john entwistle;6719 +meshuggah;6720 +chris webby;6721 +jimmy dawkins;6722 +russ taff;6723 +gabriella cilmi;6724 +balto;6725 +peetie wheatstraw;6726 +gary clark jr.;6727 +the clovers;6728 +the agony scene;6729 +roland grapow;6730 +gary stewart;6731 +buddy guy;6732 +necrodeath;6733 +st. vincent;6734 +firefall;6735 +slechtvalk;6736 +the boys;6737 +the twins;6738 +chandeen;6739 +originoo gunn clappaz;6740 +annie herring;6741 +shai linne;6742 +steve carlson;6743 +the gray havens;6744 +matthew sweet and susanna hoffs;6745 +livingston taylor;6746 +pro-pain;6747 +elbow;6748 +mandalay;6749 +sirenia;6750 +modern skirts;6751 +jasmine thompson;6752 +marcia griffiths;6753 +the swellers;6754 +michael monroe;6755 +tom rosenthal;6756 +florence + the machine;6757 +thunder;6758 +amber;6759 +grave;6760 +violent work of art;6761 +gene vincent;6762 +sarina paris;6763 +polyenso;6764 +mark seymour & the undertow;6765 +tism;6766 +the dubliners;6767 +bonnie raitt;6768 +michelle williams;6769 +blank & jones;6770 +walls of jericho;6771 +lupe fiasco;6772 +james marsters;6773 +metal church;6774 +excision;6775 +keith murray;6776 +john ogdon;6777 +the low anthem;6778 +chris merritt;6779 +maysa leak;6780 +henry fiat's open sore;6781 +ernestine anderson;6782 +capital lights;6783 +the cooper temple clause;6784 +alan jackson;6785 +hey;6786 +pathology;6787 +randy rogers band;6788 +tink;6789 +flesh field;6790 +vinyl theatre;6791 +dystopia;6792 +jill barber;6793 +the long blondes;6794 +the color morale;6795 +giuseppe verdi;6796 +karin park;6797 +amy grant;6798 +miasmal;6799 +gene watson;6800 +page & plant;6801 +acid witch;6802 +adagio;6803 +lisa ekdahl;6804 +martin page;6805 +triumvirat;6806 +s.l.a.b.;6807 +8ball & mjg;6808 +better luck next time;6809 +marble sounds;6810 +whitney houston;6811 +ringo starr;6812 +the scabs;6813 +the whitest boy alive;6814 +third eye blind;6815 +thornley;6816 +herbert grönemeyer;6817 +stereo skyline;6818 +amos lee;6819 +shawn james;6820 +parkway drive;6821 +trippie redd;6822 +vanessa carlton;6823 +guardian;6824 +blowsight;6825 +san francisco symphony;6826 +five;6827 +geoff moore;6828 +david meece;6829 +enigma;6830 +cold chisel;6831 +the impossibles;6832 +sondre lerche;6833 +hey monday;6834 +sol gabetta;6835 +machinae supremacy;6836 +p.m. dawn;6837 +johnny rivers;6838 +mickey newbury;6839 +sandy & junior;6840 +taylor swift;6841 +aaradhna;6842 +edward elgar;6843 +lamb of god;6844 +antestor;6845 +doom;6846 +arcturus;6847 +kingdom come;6848 +flo rida;6849 +afroman;6850 +mickey gilley;6851 +donna regina;6852 +erasure;6853 +leonard nimoy;6854 +susan raye;6855 +die form;6856 +allure;6857 +quincy punx;6858 +secret army;6859 +perry como;6860 +aldo nova;6861 +the loud family;6862 +the suicide file;6863 +maggie rogers;6864 +melanie;6865 +andrew lloyd webber;6866 +sparks;6867 +angels & agony;6868 +shooter jennings;6869 +m people;6870 +the story so far;6871 +aqua;6872 +scott matthews;6873 +chemlab;6874 +apollo sunshine;6875 +mason proper;6876 +bobby o;6877 +action adventure world;6878 +hawk nelson;6879 +audrey assad;6880 +jerry lee lewis;6881 +andy m. stewart;6882 +grimskunk;6883 +rudy vallée;6884 +erin mccarley;6885 +z-ro;6886 +crooked still;6887 +nadeah;6888 +marah;6889 +sinner;6890 +saint raymond;6891 +devin townsend;6892 +james young;6893 +dillon;6894 +blackrain;6895 +crisis;6896 +loney, dear;6897 +dark the suns;6898 +damone;6899 +big big train;6900 +pride & glory;6901 +cancer bats;6902 +dismantled;6903 +the cheetah girls;6904 +the saints;6905 +jonathan larson;6906 +everything but the girl;6907 +glass hammer;6908 +chairlift;6909 +scarve;6910 +mai kuraki;6911 +travie mccoy;6912 +steeleye span;6913 +chris de burgh;6914 +james otto;6915 +chris rea;6916 +forever slave;6917 +bobby vee;6918 +susannah mccorkle;6919 +goodie mob;6920 +girls aloud;6921 +lake street dive;6922 +frankenstein drag queens from planet 13;6923 +vance joy;6924 +anubis;6925 +sabrina starke;6926 +level;6927 +kick axe;6928 +nanci griffith;6929 +ben moody;6930 +epica;6931 +field music;6932 +lady antebellum;6933 +grieves;6934 +osborne brothers;6935 +judie tzuke;6936 +rick james;6937 +willie d;6938 +at the gates;6939 +daniel shafran;6940 +mr. mister;6941 +beulah;6942 +robert cray;6943 +hatesphere;6944 +tim fite;6945 +clay walker;6946 +the four seasons;6947 +vintage trouble;6948 +the rankin family;6949 +chaka khan;6950 +paul wall;6951 +brian wilson;6952 +alestorm;6953 +明星 (akeboshi);6954 +billy gilman;6955 +jennifer kimball;6956 +the charlie daniels band;6957 +john mellencamp;6958 +revamp;6959 +lost in tears;6960 +just jinger;6961 +mental as anything;6962 +dark tranquillity;6963 +c-lekktor;6964 +the trammps;6965 +hb;6966 +the ready set;6967 +joey tempest;6968 +baton rouge;6969 +lana del rey;6970 +ms. dynamite;6971 +radio birdman;6972 +cows;6973 +pansy division;6974 +klaatu;6975 +ryan delmore;6976 +laurie anderson;6977 +trespassers william;6978 +geoff berner;6979 +black sabbath;6980 +eric saade;6981 +meja;6982 +cannibal corpse;6983 +with confidence;6984 +jim jones;6985 +blake shelton;6986 +the nightwatchman;6987 +elephant man;6988 +massive attack;6989 +lee kernaghan;6990 +tomorrows bad seeds;6991 +aynsley lister;6992 +hanoi rocks;6993 +mono inc.;6994 +linton kwesi johnson;6995 +richard & linda thompson;6996 +lard;6997 +tq;6998 +blue café;6999 +blackjack;7000 +inspectah deck;7001 +harry james;7002 +no fun at all;7003 +bad brains;7004 +herman's hermits;7005 +intense;7006 +mink deville;7007 +future islands;7008 +the midnight beast;7009 +sarah connor;7010 +psycho motel;7011 +last train home;7012 +alberta cross;7013 +helen humes;7014 +easton corbin;7015 +yngwie malmsteen;7016 +tinfed;7017 +thee silver mt. zion;7018 +lalah hathaway;7019 +sheavy;7020 +slaughter;7021 +tunng;7022 +the four freshmen;7023 +cymbals eat guitars;7024 +debarge;7025 +the beatles;7026 +lower definition;7027 +michael martin murphey;7028 +bury tomorrow;7029 +twista;7030 +hazel o'connor;7031 +kerry livgren;7032 +6ix9ine;7033 +paul colman trio;7034 +clean bandit;7035 +seam;7036 +dodgy;7037 +the lovin' spoonful;7038 +art garfunkel;7039 +lee ryan;7040 +la sera;7041 +c.w. stoneking;7042 +johann christian bach;7043 +8 foot sativa;7044 +beast in black;7045 +straylight run;7046 +saves the day;7047 +robyn;7048 +the blasters;7049 +petra;7050 +halou;7051 +the neighbourhood;7052 +runrig;7053 +billy ocean;7054 +die young;7055 +rainbirds;7056 +play;7057 +atomic kitten;7058 +hallelujah the hills;7059 +amaranthe;7060 +koffin kats;7061 +swingin' utters;7062 +charlie musselwhite;7063 +phillips, craig & dean;7064 +tarkio;7065 +avulsed;7066 +unwritten law;7067 +al axy;7068 +freddie mercury;7069 +rhye;7070 +giorgio moroder;7071 +elegy;7072 +blue stahli;7073 +zachary richard;7074 +børns;7075 +bob moses;7076 +chromatics;7077 +the barr brothers;7078 +gorefest;7079 +countess;7080 +caetano veloso;7081 +jerry butler;7082 +steve harley & cockney rebel;7083 +michelle branch;7084 +dr. john;7085 +the business;7086 +handsome ghost;7087 +naked eyes;7088 +amduscia;7089 +scooter;7090 +bride;7091 +white sea;7092 +empire! empire! (i was a lonely estate);7093 +mastodon;7094 +amon amarth;7095 +mike posner;7096 +dove cameron;7097 +desmond dekker;7098 +the rugburns;7099 +harley poe;7100 +skinless;7101 +secret garden;7102 +colter wall;7103 +john cena;7104 +jump5;7105 +cat stevens;7106 +tim curry;7107 +the classic crime;7108 +grey delisle;7109 +ramblin' jack elliott;7110 +the world is a beautiful place & i am no longer afraid to die;7111 +the spinto band;7112 +the chainsmokers;7113 +clawfinger;7114 +the thrills;7115 +ultravox;7116 +quasi;7117 +wonder girls;7118 +the psycho realm;7119 +alice in chains;7120 +bill wyman's rhythm kings;7121 +quiet riot;7122 +rome;7123 +fair warning;7124 +to/die/for;7125 +lari white;7126 +backseat goodbye;7127 +rhett miller;7128 +eliza neals;7129 +conway twitty;7130 +asg;7131 +highasakite;7132 +arthur grumiaux;7133 +pieter wispelwey;7134 +union j;7135 +jon randall;7136 +allies;7137 +modern romance;7138 +krisiun;7139 +s;7140 +killa kyleon;7141 +adam lambert;7142 +skrew;7143 +imagination movers;7144 +jade warrior;7145 +beborn beton;7146 +webbie;7147 +richard o'brien;7148 +ella fitzgerald & louis armstrong;7149 +denis matsuev;7150 +kultur shock;7151 +la dispute;7152 +sean watkins;7153 +tex williams;7154 +cary brothers;7155 +joan of arc;7156 +dead hand projekt;7157 +dio;7158 +big tymers;7159 +tokyo police club;7160 +midge ure;7161 +adam cohen;7162 +forever changed;7163 +more than life;7164 +avenged sevenfold;7165 +lifetime;7166 +the clash;7167 +five finger death punch;7168 +zac brown band;7169 +just surrender;7170 +roosevelt sykes;7171 +cory morrow;7172 +岡崎律子 (ritsuko okazaki);7173 +88 fingers louie;7174 +brenton wood;7175 +bill mallonee;7176 +keziah jones;7177 +lebanon hanover;7178 +raspberries;7179 +mygrain;7180 +sita;7181 +twenty one pilots;7182 +bill withers;7183 +family force 5;7184 +t.a.t.u.;7185 +rainbow;7186 +marianas trench;7187 +cascada;7188 +the watchmen;7189 +cold;7190 +annette hanshaw;7191 +james labrie;7192 +viktoria mullova;7193 +altaria;7194 +icon of coil;7195 +oliver koletzki;7196 +kansas;7197 +michael bolton;7198 +keren ann;7199 +lil pump;7200 +john lennon & yoko ono;7201 +jim lauderdale;7202 +the manhattans;7203 +stacey kent;7204 +lee brice;7205 +endo;7206 +dani siciliano;7207 +game theory;7208 +lykke li;7209 +hoobastank;7210 +lil suzy;7211 +since october;7212 +tinchy stryder;7213 +camera obscura;7214 +macabre;7215 +16 volt;7216 +merle haggard;7217 +i am abomination;7218 +nana mouskouri;7219 +tift merritt;7220 +optiganally yours;7221 +dwight twilley;7222 +evgeny kissin;7223 +david grisman;7224 +ohio players;7225 +liberty x;7226 +matt haimovitz;7227 +robbie williams;7228 +grayson & whitter;7229 +dream evil;7230 +beau;7231 +t.j. miller;7232 +the bar-kays;7233 +u.d.o.;7234 +keke palmer;7235 +ambrosia;7236 +aswad;7237 +henry mancini;7238 +frida hyvönen;7239 +shakespears sister;7240 +celph titled;7241 +pigeon john;7242 +on broken wings;7243 +javier;7244 +billy currington;7245 +a silent film;7246 +sly & the family stone;7247 +stephen duffy;7248 +vicki lawrence;7249 +lucky dube;7250 +the georgia satellites;7251 +bonnie tyler;7252 +press play;7253 +the academy is...;7254 +strfkr;7255 +steeler;7256 +haystak;7257 +frank black;7258 +hot chocolate;7259 +margo price;7260 +club 8;7261 +rick astley;7262 +bone thugs-n-harmony;7263 +true widow;7264 +mark king;7265 +the rascals;7266 +vanden plas;7267 +cocteau twins;7268 +london elektricity;7269 +the triffids;7270 +jolie holland;7271 +sole;7272 +ben taylor;7273 +equatronic;7274 +the million dollar quartet;7275 +jean beauvoir;7276 +marillion;7277 +tom cochrane;7278 +friend 'n fellow;7279 +jeremy camp;7280 +7th cycle;7281 +peter, paul & mary;7282 +hadise;7283 +dark angel;7284 +dark age;7285 +bo diddley;7286 +the pineapple thief;7287 +eli sostre;7288 +psapp;7289 +a loss for words;7290 +taylor dayne;7291 +hanne kah;7292 +paul young;7293 +swim deep;7294 +kanye west;7295 +scott mckenzie;7296 +epmd;7297 +anthony phillips;7298 +silent civilian;7299 +strange majik;7300 +lisa thiel;7301 +shad;7302 +joseph arthur and the lonely astronauts;7303 +a life once lost;7304 +scarling.;7305 +the stanley brothers;7306 +nat stuckey;7307 +full blown chaos;7308 +mark knopfler & emmylou harris;7309 +the wedding;7310 +the weepies;7311 +geto boys;7312 +disclosure;7313 +tonio k;7314 +brave saint saturn;7315 +the proclaimers;7316 +matthew ryan;7317 +ernest tubb;7318 +cibelle;7319 +cause for effect;7320 +milburn;7321 +cherry poppin' daddies;7322 +berlin;7323 +reverend bizarre;7324 +brazzaville;7325 +george "harmonica" smith;7326 +garfunkel and oates;7327 +ashley tisdale;7328 +james mcmurtry;7329 +vendetta;7330 +bon iver;7331 +steelheart;7332 +horrorpops;7333 +neuroticfish;7334 +airbourne;7335 +brick & lace;7336 +dead meadow;7337 +the cave singers;7338 +moneybrother;7339 +audra mcdonald;7340 +ensiferum;7341 +2 unlimited;7342 +mason jennings;7343 +a flock of seagulls;7344 +tiger army;7345 +bikini kill;7346 +the vibrators;7347 +the pillows;7348 +shocking blue;7349 +luca turilli;7350 +soen;7351 +roger miret and the disasters;7352 +magica;7353 +mac demarco;7354 +antimatter;7355 +tommy james;7356 +nine lashes;7357 +discordance axis;7358 +against me!;7359 +stavesacre;7360 +the meads of asphodel;7361 +blood stain child;7362 +ohbijou;7363 +little simz;7364 +abigail washburn;7365 +the felice brothers;7366 +running wild;7367 +a.a. bondy;7368 +bitch;7369 +die happy;7370 +pepper;7371 +long john baldry;7372 +the eyes of a traitor;7373 +fran ois couperin;7374 +the shangri-las;7375 +diana ross & the supremes and the temptations;7376 +mgła;7377 +the scary jokes;7378 +spandau ballet;7379 +sophie ellis-bextor;7380 +stauros;7381 +chris cornell;7382 +slade;7383 +medina;7384 +dr. feelgood;7385 +louis armstrong;7386 +sticky fingaz;7387 +steve perry;7388 +the vincent black shadow;7389 +procol harum;7390 +pig;7391 +a house;7392 +dead and divine;7393 +artillery;7394 +tape five;7395 +tommy dorsey;7396 +new york dolls;7397 +mull historical society;7398 +richard thompson;7399 +don francisco;7400 +charles manson;7401 +rotten sound;7402 +stevie b;7403 +scapegoat;7404 +soul embraced;7405 +the sound of animals fighting;7406 +steven isserlis;7407 +marissa nadler;7408 +mia doi todd;7409 +warbringer;7410 +giuseppe tartini;7411 +the coup;7412 +samhain;7413 +hue and cry;7414 +cut copy;7415 +blue tears;7416 +steve forbert;7417 +kingdom of sorrow;7418 +aviators;7419 +soulsavers;7420 +ike & tina turner;7421 +the band;7422 +drenge;7423 +sarah jarosz;7424 +stephan eicher;7425 +killing joke;7426 +nominon;7427 +texas in july;7428 +justin hayward;7429 +gary puckett & the union gap;7430 +kings of convenience;7431 +look what i did;7432 +sarah harmer;7433 +king adora;7434 +danny michel;7435 +iration;7436 +kate & anna mcgarrigle;7437 +pep love;7438 +eric burdon;7439 +ace frehley;7440 +wolfgang amadeus mozart;7441 +the working title;7442 +knife party;7443 +wizard;7444 +a lot like birds;7445 +cody simpson;7446 +land of talk;7447 +the kentucky headhunters;7448 +matt pond pa;7449 +casual;7450 +anaïs mitchell;7451 +phoebe carrai;7452 +funkadelic;7453 +richard strauss;7454 +ray charles;7455 +s.o.a.p.;7456 +tnt;7457 +nas;7458 +the commitments;7459 +lany;7460 +and also the trees;7461 +the rumour said fire;7462 +bonaparte;7463 +the moog;7464 +rza;7465 +northern kings;7466 +the pale fountains;7467 +for today;7468 +fyfe;7469 +mumakil;7470 +air;7471 +periphery;7472 +the xx;7473 +yvonne elliman;7474 +murs;7475 +joy division;7476 +p.o.d.;7477 +informatik;7478 +fu manchu;7479 +razakel;7480 +dappled cities;7481 +christine fellows;7482 +ion dissonance;7483 +don gibson;7484 +anvil;7485 +lobo;7486 +phillip boa & the voodooclub;7487 +pulp;7488 +moriz rosenthal;7489 +run level zero;7490 +the funeral pyre;7491 +american juniors;7492 +steelwing;7493 +chic;7494 +gustav holst;7495 +pyramaze;7496 +f-minus;7497 +wyrd;7498 +wolfpakk;7499 +kool keith;7500 +sleeping giant;7501 +the loved ones;7502 +the echoing green;7503 +edgar winter;7504 +angelus apatrida;7505 +dante;7506 +senses fail;7507 +dave carter & tracy grammer;7508 +gary wright;7509 +the saturdays;7510 +blindspott;7511 +falkenbach;7512 +outkast;7513 +xp8;7514 +pentatonix;7515 +yourcodenameis;7516 +moloko;7517 +darkane;7518 +kris kristofferson;7519 +barry mcguire;7520 +cancerslug;7521 +hangar;7522 +sirus;7523 +sammy davis jr.;7524 +trademark;7525 +dennis deyoung;7526 +kyuss;7527 +naia izumi;7528 +whose line is it anyway? cast;7529 +bastro;7530 +flora cash;7531 +turnpike troubadours;7532 +sam cooke;7533 +matisyahu;7534 +jungle rot;7535 +weekend nachos;7536 +microwave dave & the nukes;7537 +dan hartman;7538 +the cramps;7539 +cryptic wintermoon;7540 +apocalypse hoboken;7541 +fugazi;7542 +tye tribbett;7543 +karla bonoff;7544 +holly throsby;7545 +from first to last;7546 +fiction family;7547 +21 savage;7548 +free throw;7549 +xlooking forwardx;7550 +flatt & scruggs;7551 +heather nova;7552 +vandenberg;7553 +rick ross;7554 +arcane;7555 +balkan beat box;7556 +alaska thunderfuck;7557 +halsey;7558 +the menzingers;7559 +iona;7560 +peter frampton;7561 +the agonist;7562 +american aquarium;7563 +enon;7564 +cranes;7565 +revocation;7566 +chet atkins;7567 +bound for glory;7568 +the clancy brothers;7569 +kataklysm;7570 +juelz santana;7571 +superchick;7572 +hellogoodbye;7573 +travis;7574 +the grouch;7575 +born from pain;7576 +busdriver;7577 +brooke fraser;7578 +10 years;7579 +the tony rich project;7580 +streetlight manifesto;7581 +i killed the prom queen;7582 +jan howard;7583 +fats waller;7584 +jacques offenbach;7585 +alexis taylor;7586 +turk;7587 +streetheart;7588 +7 seconds;7589 +bruce hornsby;7590 +van hunt;7591 +wynonna judd;7592 +roger chapman;7593 +pink cream 69;7594 +the ballroom thieves;7595 +genesis;7596 +breakdown of sanity;7597 +tommy page;7598 +wormrot;7599 +deuce;7600 +charles bronson;7601 +something corporate;7602 +the showdown;7603 +the lonely island;7604 +bobby valentino;7605 +akon;7606 +steve mason;7607 +dual core;7608 +the church;7609 +j church;7610 +dino ciani;7611 +kent;7612 +emerson, lake & palmer;7613 +the tangent;7614 +the everly brothers;7615 +billy joe shaver;7616 +chavez;7617 +jessica simpson;7618 +sinheresy;7619 +tommy roe;7620 +agnes obel;7621 +the pretty reckless;7622 +jermaine stewart;7623 +soja;7624 +joy;7625 +the aquabats!;7626 +hot dad;7627 +sheryl crow;7628 +yo la tengo;7629 +naked aggression;7630 +neon synthesis;7631 +raghav;7632 +climie fisher;7633 +kenny chesney;7634 +little big town;7635 +alan parsons;7636 +linkin park;7637 +laibach;7638 +dar williams;7639 +наив;7640 +john foxx;7641 +this bike is a pipe bomb;7642 +buck owens & susan raye;7643 +straight faced;7644 +johnny clegg;7645 +player;7646 +gaetano donizetti;7647 +alabama thunderpussy;7648 +khia;7649 +rascal flatts;7650 +the marvelettes;7651 +thirteen senses;7652 +saidian;7653 +nrbq;7654 +trocadero;7655 +i.d.o.4.;7656 +richard swift;7657 +krezip;7658 +abc;7659 +bell book & candle;7660 +vera lynn;7661 +b'z;7662 +girls rituals;7663 +kevin welch;7664 +rich mullins;7665 +down with webster;7666 +tonic;7667 +demiricous;7668 +menomena;7669 +guillemots;7670 +monrose;7671 +carson robison;7672 +porter wagoner;7673 +ivan moravec;7674 +siobhan donaghy;7675 +the bellrays;7676 +the arka teks;7677 +tonedeff;7678 +david essex;7679 +immortal technique;7680 +buddy moss;7681 +acid house kings;7682 +mister monster;7683 +the monochrome set;7684 +the dignity of labour;7685 +shawn desman;7686 +the mamas & the papas;7687 +the handsome family;7688 +endanger;7689 +south park;7690 +karen clark sheard;7691 +dressy bessy;7692 +sweet comfort band;7693 +darden smith;7694 +slim cessna's auto club;7695 +cher;7696 +tom waits;7697 +hanne hukkelberg;7698 +beres hammond;7699 +kayo dot;7700 +the cliks;7701 +years & years;7702 +fraggle rock;7703 +brandtson;7704 +lukas nelson & promise of the real;7705 +furry lewis;7706 +jim noir;7707 +in fear and faith;7708 +ultra;7709 +a global threat;7710 +all them witches;7711 +forbidden;7712 +keith & kristyn getty;7713 +edison glass;7714 +discount;7715 +thrush hermit;7716 +joanie sommers;7717 +vampire weekend;7718 +oi polloi;7719 +the bianca story;7720 +unsung zeros;7721 +circle jerks;7722 +pascal rog ;7723 +the 88;7724 +we shot the moon;7725 +blutengel;7726 +demon hunter;7727 +westside connection;7728 +sho baraka;7729 +the roots;7730 +hoyt axton;7731 +bleach;7732 +the corries;7733 +timbaland & magoo;7734 +carl orff;7735 +emmerson nogueira;7736 +bob geldof;7737 +mortician;7738 +david ball;7739 +blood tsunami;7740 +john denver;7741 +the klf;7742 +mark erelli;7743 +pat travers;7744 +tina turner;7745 +rhonda vincent;7746 +entombed;7747 +stutterfly;7748 +lou rawls;7749 +blaque;7750 +connie smith;7751 +utada hikaru;7752 +zhu;7753 +why don't we;7754 +beachwood sparks;7755 +the l-train;7756 +beth orton;7757 +guiomar novaes;7758 +animosity;7759 +deborah allen;7760 +the real tuesday weld;7761 +janelle monáe;7762 +!!!;7763 +hayley westenra;7764 +avicii;7765 +lil yachty;7766 +brazilian girls;7767 +the babys;7768 +mirah;7769 +rockapella;7770 +the posies;7771 +eden synthetic corps;7772 +bright eyes;7773 +black knights;7774 +hoodoo gurus;7775 +drain sth;7776 +babe ruth;7777 +watain;7778 +lil b;7779 +t'pau;7780 +joe jackson;7781 +june christy;7782 +josh turner;7783 +carly simon;7784 +becoming the archetype;7785 +alexisonfire;7786 +paulson;7787 +make them suffer;7788 +drake;7789 +billy thorpe;7790 +earth, wind & fire;7791 +belleruche;7792 +the housemartins;7793 +the chariot;7794 +jefferson starship;7795 +wolf gang;7796 +roch voisine;7797 +parachute;7798 +ferruccio busoni;7799 +grave digger;7800 +piebald;7801 +bob dylan;7802 +wax;7803 +eric fish;7804 +mark spiro;7805 +the seatbelts;7806 +dawn richard;7807 +usher;7808 +lmfao;7809 +i monster;7810 +mikhail glinka;7811 +nombe;7812 +s club 7;7813 +ray davies;7814 +dusty springfield;7815 +hieroglyphics;7816 +steril;7817 +vladimir sofronitsky;7818 +大塚愛 (ai otsuka);7819 +brendan benson;7820 +cyferdyne;7821 +fantasia;7822 +zola jesus;7823 +october fall;7824 +she & him;7825 +trixter;7826 +damien rice;7827 +delain;7828 +dave stewart & the spiritual cowboys;7829 +little boots;7830 +crystallion;7831 +rusted root;7832 +blanks 77;7833 +dirty looks;7834 +within reason;7835 +casey donahew band;7836 +aythis;7837 +the world of skin;7838 +propaganda;7839 +tom russell;7840 +julia stone;7841 +emigrate;7842 +vaya con dios;7843 +tove lo;7844 +death by stereo;7845 +stevie ray vaughan;7846 +nim vind;7847 +sonny terry & brownie mcghee;7848 +sam phillips;7849 +b! machine;7850 +julio iglesias;7851 +john wetton;7852 +edgar broughton band;7853 +dr. alban;7854 +mars ill;7855 +immaculate machine;7856 +martyr defiled;7857 +free dominguez;7858 +atreyu;7859 +johnny burnette;7860 +maria mena;7861 +spheric universe experience;7862 +whitehouse;7863 +zed;7864 +andrea bocelli;7865 +tommy james and the shondells;7866 +malcolm middleton;7867 +suicide commando;7868 +mark owen;7869 +the string cheese incident;7870 +patti austin;7871 +jethro tull;7872 +jennifer lopez;7873 +dorothy;7874 +ayria;7875 +guru;7876 +burton cummings;7877 +the warren brothers;7878 +a1;7879 +cody jinks;7880 +billy squier;7881 +junius;7882 +never shout never;7883 +the cryan' shames;7884 +the heavy;7885 +myra hess;7886 +television;7887 +sadist;7888 +danger danger;7889 +clique girlz;7890 +jamie lawson;7891 +rosanne cash;7892 +walk off the earth;7893 +scorpions;7894 +kelly clarkson;7895 +unknown;0 +speaker;7896 +singer;7897 diff --git a/jukebox/data/ids/v3_genre_ids.txt b/jukebox/data/ids/v3_genre_ids.txt new file mode 100644 index 0000000000000000000000000000000000000000..eb8a17b2cd09397d5236d50a47328d4dd6ef3a69 --- /dev/null +++ b/jukebox/data/ids/v3_genre_ids.txt @@ -0,0 +1,604 @@ +electroclash;1 +acid rock;2 +christian metal;3 +pop rock;4 +gothic;5 +big beat;6 +psychedelic rock‎;7 +funk carioca;8 +bebop;9 +dance punk;10 +trad jazz;11 +romantic;12 +andean music;13 +volksmusik;14 +coldwave;15 +gospel blues;16 +italian folk;17 +disney;18 +dark wave‏‎;19 +powerviolence;20 +bachata;21 +soft rock;22 +s music"];23 +bubblegum dance;24 +western swing;25 +alternative country;26 +latin pop;27 +eurobeat;28 +n;29 +unblack metal;30 +surf;31 +nu-disco;32 +event;33 +classical;34 +nasheed;35 +jovem guarda;36 +british blues;37 +bossa nova;38 +detroit blues;39 +rock;40 +contemporary christian;41 +dark ambient;42 +noise rock;43 +axé;44 +soca;45 +dance-rock;46 +contemporary jazz;47 +appalachian folk;48 +humppa‎;49 +ambient;50 +funeral doom;51 +southern gospel;52 +video game‎;53 +hip hop;54 +glitch hop;55 +krautrock;56 +breakcore;57 +ska;58 +traditional folk;59 +psychedelic trance;60 +reggae‏‎;61 +noise pop;62 +drumstep;63 +house;64 +teen pop;65 +sea shanties;66 +junkanoo;67 +mandopop;68 +pre-war blues;69 +doom metal;70 +oi-punk;71 +swamp rock;72 +crunkcore;73 +rap rock;74 +roots;75 +country rap;76 +avant-garde;77 +cumbia;78 +glam metal;79 +groove metal;80 +electric blues;81 +new orleans rhythm and blues;82 +canadian hip hop;83 +freestyle;84 +deathgrind;85 +idm;86 +comedy rock;87 +art punk;88 +progg;89 +work songs;90 +art pop;91 +conjunto;92 +persian;93 +parody;94 +jazz-funk;95 +french hip hop;96 +spirituals;97 +african;98 +middle-eastern;99 +minimal;100 +ranchera;101 +industrial rock;102 +electro house;103 +celtic rock;104 +death doom;105 +grupera;106 +jazz fusion‎;107 +political folk;108 +christian punk;109 +rapcore;110 +j-pop;111 +mashup;112 +metalcore;113 +progressive country;114 +power noise;115 +hip house;116 +crossover thrash;117 +electropop‎;118 +psychedelic folk;119 +punk rock;120 +classic rock;121 +zydeco;122 +afrobeat;123 +salsa;124 +banda;125 +chill-out;126 +morna;127 +minnesang;128 +alternative metal;129 +djent;130 +african folk;131 +mambo;132 +sertanejo;133 +classic pop;134 +soul;135 +australian hip hop;136 +symphonic rock;137 +celtic punk;138 +synthpop‎;139 +europop;140 +funk;141 +jazz blues;142 +vocal trance;143 +celtic fusion;144 +industrial;145 +kirtan;146 +slowcore;147 +flamenco;148 +piano blues;149 +texas blues;150 +aggrotech;151 +steampunk;152 +opera;153 +folktronica;154 +klezmer;155 +nwobhm;156 +goregrind;157 +rac;158 +neo-psychedelia‏‎;159 +post-rock‎;160 +hard bop;161 +gypsy jazz;162 +new orleans blues;163 +doo-wop;164 +soul blues;165 +trap;166 +indietronica;167 +psychobilly;168 +euro disco;169 +neo-progressive rock;170 +canterbury;171 +freak folk;172 +midwest rap;173 +instrumental rock;174 +dance-pop;175 +avant-garde metal;176 +edm;177 +deep house;178 +progressive bluegrass;179 +rave;180 +australian folk;181 +comic opera;182 +sunshine pop;183 +gregorian chant;184 +psychedelic rock;185 +honky tonk;186 +rock 'n' roll;187 +television;188 +nintendocore;189 +jump blues;190 +roots reggae;191 +traditional bluegrass;192 +operatic pop;193 +skate punk;194 +reggaeton;195 +manele;196 +middle-eastern hip hop;197 +skiffle;198 +nsbm;199 +nu jazz;200 +disco;201 +horrorcore;202 +early music;203 +post-bop;204 +gothic rock;205 +crack rock steady;206 +easy listening;207 +psychedelic;208 +christian;209 +brutal death metal;210 +experimental rock;211 +modern classical‎;212 +drum and bass;213 +dark wave;214 +dubstep;215 +grunge;216 +christian hip hop;217 +latin jazz;218 +r&b;219 +s music", ;220 +free jazz;221 +experimental hip hop;222 +swing;223 +smooth jazz;224 +southern metal;225 +religious;226 +progressive death metal;227 +contemporary folk;228 +j-rock;229 +jazz;230 +hamburger schule;231 +teen pop‎;232 +crossover;233 +italo disco;234 +deathcore;235 +blues;236 +crunk;237 +jangle pop;238 +indian classical music;239 +big band;240 +proto-punk;241 +dirty blues;242 +garage punk;243 +extreme metal;244 +folk metal;245 +neo soul;246 +electric folk;247 +synthwave;248 +arena rock;249 +post-grunge;250 +indie rock;251 +acoustic blues;252 +native american;253 +progressive trance;254 +nu metal;255 +digital hardcore;256 +brazilian rock;257 +funky house;258 +symphonic black metal;259 +lounge music;260 +brega;261 +trance;262 +industrial metal;263 +austropop;264 +bhangra;265 +new wave;266 +neoclassical;267 +post-metal;268 +dub;269 +industrial metal‎;270 +irish folk;271 +deutschrock;272 +gypsy;273 +dark electro;274 +alternative hip hop;275 +mbaqanga;276 +swamp blues;277 +french pop;278 +tango;279 +rockabilly;280 +old-time music;281 +blues rock;282 +scottish folk;283 +indie folk;284 +nazi-punk;285 +deutschpunk;286 +piedmont blues;287 +beatbox;288 +worship;289 +heavy metal;290 +underground hip hop;291 +mixed;292 +electro;293 +tropicalismo;294 +jazz fusion;295 +worldbeat;296 +hill country blues;297 +a cappella;298 +dixieland;299 +hi-nrg;300 +punk blues;301 +anti-folk;302 +east coast blues;303 +polka;304 +mod revival;305 +soundtrack/musical;306 +movie;307 +outlaw country;308 +rock against communism;309 +barbershop;310 +math rock;311 +avant-garde‎;312 +psychedelic pop;313 +synthpop;314 +post-punk‎;315 +queercore;316 +death metal;317 +political hip hop;318 +thrashcore;319 +acid house;320 +post-hardcore‎;321 +electro-industrial;322 +rio;323 +southern hip hop;324 +filk;325 +duranguense;326 +latin hip hop;327 +pop punk;328 +space rock;329 +j-rap;330 +deep house‎;331 +baroque pop;332 +chiptune;333 +heartland rock;334 +dancehall;335 +experimental pop;336 +adult contemporary‎;337 +boogie woogie;338 +country pop;339 +power pop;340 +west coast hip hop;341 +thrash metal;342 +avant-pop;343 +enka;344 +k-pop;345 +post-britpop;346 +vocalese;347 +volkslied;348 +reggae fusion;349 +funk rock;350 +tech house;351 +adult contemporary;352 +death 'n' roll;353 +russian rock;354 +latin rock;355 +folk punk;356 +west coast blues;357 +progressive black metal;358 +progressive metal;359 +cajun;360 +sophisti-pop;361 +rock 'n' roll‎;362 +post-punk;363 +symphonic metal;364 +beat;365 +alternative rock‎;366 +art rock;367 +bakersfield sound;368 +indie pop;369 +folk;370 +acid jazz;371 +dream pop;372 +pop-rap;373 +eurodance;374 +vaudeville;375 +louisiana blues;376 +baião;377 +downtempo;378 +jug band;379 +neo-psychedelia;380 +sufi;381 +medieval;382 +singer-songwriter‎;383 +outsider music;384 +pop-folk;385 +martial industrial;386 +samba;387 +alternative dance;388 +children's music‎;389 +anarcho-punk;390 +dark rock;391 +rock en español;392 +balearic beat;393 +electropunk;394 +urban contemporary;395 +ragtime;396 +british invasion;397 +bubblegum pop;398 +rap metal;399 +soundtrack/television;400 +blues revival;401 +reggae;402 +schlager;403 +dance band;404 +video game;405 +crust punk;406 +cabaret;407 +ska punk‎;408 +bolero;409 +canadian folk;410 +neofolk;411 +shoegazing;412 +acoustic;413 +modern classical;414 +swamp pop;415 +celtic;416 +futurepop;417 +g-funk;418 +norteño;419 +orchestral;420 +boogie rock;421 +tejano;422 +new age;423 +soul jazz;424 +cantopop;425 +progressive metalcore;426 +mathcore;427 +new rave;428 +neue deutsche welle;429 +delta blues;430 +lo-fi;431 +poetry;432 +hatecore;433 +chanson;434 +underground hip hop;435 +pirate metal;436 +trip hop;437 +fado;438 +americana;439 +hardcore hip hop;440 +post-industrial;441 +grime;442 +southern rock;443 +grindcore;444 +musical;445 +hard trance;446 +ska punk;447 +post-rock;448 +uk garage;449 +melodic metalcore;450 +black metal;451 +visual kei;452 +soundtrack;453 +axé‎;454 +hardcore punk;455 +western;456 +blackgaze;457 +christian rock;458 +technical death metal;459 +christian hardcore;460 +christmas;461 +breakbeat;462 +francophone;463 +choral;464 +progressive folk;465 +mystic folk;466 +melodic death metal;467 +horror punk;468 +country blues;469 +nederpop;470 +post-hardcore;471 +future garage;472 +techno;473 +swiss rock;474 +dance-pop‎;475 +electronicore;476 +post-punk revival;477 +glitch;478 +calypso;479 +ragga;480 +britpop;481 +rock opera;482 +cowpunk;483 +la confusion des genres;484 +alternative rock;485 +surf rock;486 +ballad;487 +latin;488 +contemporary r&b;489 +forró;490 +ethereal wave;491 +electro swing;492 +novelty;493 +funk melody;494 +punk cabaret;495 +symphonic metal‎;496 +pop;497 +paisley underground;498 +neue deutsche härte;499 +glam rock;500 +nerdcore hip hop;501 +bluegrass;502 +hardstyle;503 +happy hardcore;504 +baroque;505 +speed metal;506 +country;507 +electropop;508 +memphis blues;509 +pagan metal;510 +horror punk‏‎;511 +mariachi;512 +singer-songwriter;513 +children's music;514 +boogie;515 +gothic metal;516 +electronic rock;517 +emo;518 +gospel;519 +ebm;520 +roots rock;521 +vocal;522 +celtic folk;523 +electronic;524 +death metal;525 +gabber;526 +deathrock;527 +experimental;528 +spoken word;529 +screamo;530 +finnish folk;531 +singer only;532 +new jack swing;533 +acid techno;534 +corrido;535 +english folk;536 +american folk;537 +raï;538 +drone doom;539 +hard rock;540 +piano rock;541 +hawaiian;542 +humppa;543 +east coast hip hop;544 +gypsy punk;545 +country rock;546 +jazz‎;547 +mpb;548 +harmonica blues;549 +melodic hardcore;550 +string band;551 +anime;552 +nu metalcore;553 +progressive rock;554 +garage rock;555 +dance;556 +reggae rock;557 +contemporary christian‎;558 +sludge metal;559 +minimal techno;560 +folk rock;561 +drone music;562 +stoner rock;563 +speedcore;564 +chillwave;565 +riot grrrl;566 +chamber music;567 +cool jazz;568 +noise;569 +vocal jazz;570 +progressive rock;571 +afropop;572 +bro-country;573 +goa trance;574 +2-tone;575 +miami bass;576 +quiet storm;577 +pub rock;578 +power metal;579 +blue-eyed soul;580 +viking metal;581 +gangsta rap;582 +country pop‎;583 +exotica;584 +christian ska;585 +jam band;586 +chicago blues;587 +street punk;588 +funk metal;589 +rap metal;590 +christian hymns;591 +classic female blues;592 +kizomba;593 +comedy;594 +dark cabaret;595 +french house;596 +progressive house;597 +african blues;598 +atmospheric black metal;599 +pop rock‎;600 +blackened death metal;601 +shibuya-kei;602 +electronica;603 +unknown;0 diff --git a/jukebox/data/labels.py b/jukebox/data/labels.py new file mode 100644 index 0000000000000000000000000000000000000000..00bb4059d17cb3a917dcaaaea74b1f3706bcf4b9 --- /dev/null +++ b/jukebox/data/labels.py @@ -0,0 +1,130 @@ +import torch as t +import numpy as np +from jukebox.data.artist_genre_processor import ArtistGenreProcessor +from jukebox.data.text_processor import TextProcessor + +# Linear window heurisic to get a window of lyric_tokens +def get_relevant_lyric_tokens(full_tokens, n_tokens, total_length, offset, duration): + if len(full_tokens) < n_tokens: + tokens = [0] * (n_tokens - len(full_tokens)) + full_tokens + indices = [-1] * (n_tokens - len(full_tokens)) + list(range(0, len(full_tokens))) + else: + assert 0 <= offset < total_length + midpoint = int(len(full_tokens) * (offset + duration / 2.0) / total_length) + midpoint = min(max(midpoint, n_tokens // 2), len(full_tokens) - n_tokens // 2) + tokens = full_tokens[midpoint - n_tokens // 2:midpoint + n_tokens // 2] + indices = list(range(midpoint - n_tokens // 2, midpoint + n_tokens // 2)) + assert len(tokens) == n_tokens, f"Expected length {n_tokens}, got {len(tokens)}" + assert len(indices) == n_tokens, f"Expected length {n_tokens}, got {len(indices)}" + assert tokens == [full_tokens[index] if index != -1 else 0 for index in indices] + return tokens, indices + +class EmptyLabeller(): + def get_label(self, artist=None, genre=None, lyrics=None, total_length=None, offset=None): + y = np.array([], dtype=np.int64) + info = dict(artist="n/a", genre="n/a", lyrics=[], full_tokens=[]) + return dict(y=y, info=info) + + def get_batch_labels(self, metas, device='cpu'): + ys, infos = [], [] + for meta in metas: + label = self.get_label() + y, info = label['y'], label['info'] + ys.append(y) + infos.append(info) + + ys = t.stack([t.from_numpy(y) for y in ys], dim=0).to(device).long() + assert ys.shape[0] == len(metas) + assert len(infos) == len(metas) + return dict(y=ys, info=infos) + +class Labeller(): + def __init__(self, max_genre_words, n_tokens, sample_length, v3=False): + self.ag_processor = ArtistGenreProcessor(v3) + self.text_processor = TextProcessor(v3) + self.n_tokens = n_tokens + self.max_genre_words = max_genre_words + self.sample_length = sample_length + self.label_shape = (4 + self.max_genre_words + self.n_tokens, ) + + def get_label(self, artist, genre, lyrics, total_length, offset): + artist_id = self.ag_processor.get_artist_id(artist) + genre_ids = self.ag_processor.get_genre_ids(genre) + + lyrics = self.text_processor.clean(lyrics) + full_tokens = self.text_processor.tokenise(lyrics) + tokens, _ = get_relevant_lyric_tokens(full_tokens, self.n_tokens, total_length, offset, self.sample_length) + + assert len(genre_ids) <= self.max_genre_words + genre_ids = genre_ids + [-1] * (self.max_genre_words - len(genre_ids)) + y = np.array([total_length, offset, self.sample_length, artist_id, *genre_ids, *tokens], dtype=np.int64) + assert y.shape == self.label_shape, f"Expected {self.label_shape}, got {y.shape}" + info = dict(artist=artist, genre=genre, lyrics=lyrics, full_tokens=full_tokens) + return dict(y=y, info=info) + + def get_y_from_ids(self, artist_id, genre_ids, lyric_tokens, total_length, offset): + assert len(genre_ids) <= self.max_genre_words + genre_ids = genre_ids + [-1] * (self.max_genre_words - len(genre_ids)) + if self.n_tokens > 0: + assert len(lyric_tokens) == self.n_tokens + else: + lyric_tokens = [] + y = np.array([total_length, offset, self.sample_length, artist_id, *genre_ids, *lyric_tokens], dtype=np.int64) + assert y.shape == self.label_shape, f"Expected {self.label_shape}, got {y.shape}" + return y + + def get_batch_labels(self, metas, device='cpu'): + ys, infos = [], [] + for meta in metas: + label = self.get_label(**meta) + y, info = label['y'], label['info'] + ys.append(y) + infos.append(info) + + ys = t.stack([t.from_numpy(y) for y in ys], dim=0).to(device).long() + assert ys.shape[0] == len(metas) + assert len(infos) == len(metas) + return dict(y=ys, info=infos) + + def set_y_lyric_tokens(self, ys, labels): + info = labels['info'] + assert ys.shape[0] == len(info) + if self.n_tokens > 0: + # total_length, offset, duration): + tokens_list = [] + indices_list = [] # whats the index of each current character in original array + for i in range(ys.shape[0]): + full_tokens = info[i]['full_tokens'] + total_length, offset, duration = ys[i, 0], ys[i, 1], ys[i, 2] + tokens, indices = get_relevant_lyric_tokens(full_tokens, self.n_tokens, total_length, offset, duration) + tokens_list.append(tokens) + indices_list.append(indices) + ys[:, -self.n_tokens:] = t.tensor(tokens_list, dtype=t.long, device='cuda') + return indices_list + else: + return None + + def describe_label(self, y): + assert y.shape == self.label_shape, f"Expected {self.label_shape}, got {y.shape}" + y = np.array(y).tolist() + total_length, offset, length, artist_id, *genre_ids = y[:4 + self.max_genre_words] + tokens = y[4 + self.max_genre_words:] + artist = self.ag_processor.get_artist(artist_id) + genre = self.ag_processor.get_genre(genre_ids) + lyrics = self.text_processor.textise(tokens) + return dict(artist=artist, genre=genre, lyrics=lyrics) + + +if __name__ == '__main__': + labeller = Labeller(5, 512, 8192*8*4*4, v3=False) + label = labeller.get_label("Alan Jackson", "Country Rock", "old town road", 4*60*44100, 0) + print(label, labeller.describe_label(label['y'])) + + labeller = Labeller(1, 384, 6144*8*4*4, v3=True) + label = labeller.get_label("Alan Jackson", "Country Rock", "old town road", 4*60*44100, 0) + print(label, labeller.describe_label(label['y'])) + + + + + diff --git a/jukebox/data/text_processor.py b/jukebox/data/text_processor.py new file mode 100644 index 0000000000000000000000000000000000000000..5581ab3c5e2d975ae17ede10072f945cc3237021 --- /dev/null +++ b/jukebox/data/text_processor.py @@ -0,0 +1,32 @@ +import re +from unidecode import unidecode + +class TextProcessor(): + def __init__(self, v3=False): + if v3: + vocab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,:;!?-\'\"()[] \t\n' + not_vocab = re.compile('[^A-Za-z0-9.,:;!?\-\'\"()\[\] \t\n]+') + else: + vocab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,:;!?-+\'\"()[] \t\n' + not_vocab = re.compile('[^A-Za-z0-9.,:;!?\-+\'\"()\[\] \t\n]+') + self.vocab = {vocab[index]: index + 1 for index in range(len(vocab))} + self.vocab[''] = 0 + self.n_vocab = len(vocab) + 1 + self.tokens = {v: k for k, v in self.vocab.items()} + self.tokens[0] = '' # became '' + self.not_vocab = not_vocab + + def clean(self, text): + text = unidecode(text) # Convert to ascii + text = text.replace('\\', '\n') + text = self.not_vocab.sub('', text) # Remove non vocab + return text + + def tokenise(self, text): + return [self.vocab[char] for char in text] + + def textise(self, tokens): + return ''.join([self.tokens[token] for token in tokens]) + + def characterise(self, tokens): + return [self.tokens[token] for token in tokens] diff --git a/jukebox/hparams.py b/jukebox/hparams.py new file mode 100644 index 0000000000000000000000000000000000000000..eb74584aa1f30a5520bd3329044edf0739f1e983 --- /dev/null +++ b/jukebox/hparams.py @@ -0,0 +1,567 @@ +HPARAMS_REGISTRY = {} +DEFAULTS = {} + +class Hyperparams(dict): + def __getattr__(self, attr): + return self[attr] + + def __setattr__(self, attr, value): + self[attr] = value + +def setup_hparams(hparam_set_names, kwargs): + H = Hyperparams() + if not isinstance(hparam_set_names, tuple): + hparam_set_names = hparam_set_names.split(",") + hparam_sets = [HPARAMS_REGISTRY[x.strip()] for x in hparam_set_names if x] + [kwargs] + for k, v in DEFAULTS.items(): + H.update(v) + for hps in hparam_sets: + for k in hps: + if k not in H: + raise ValueError(f"{k} not in default args") + H.update(**hps) + H.update(**kwargs) + return H + +# Teeny for testing +teeny = Hyperparams( +) +HPARAMS_REGISTRY["teeny"] = teeny + +easy = Hyperparams( + sr=22050, +) +HPARAMS_REGISTRY["easy"] = easy + +REMOTE_PREFIX = 'https://openaipublic.azureedge.net/' + +# Model hps +vqvae = Hyperparams( + levels = 3, + downs_t = (3, 2, 2), + strides_t = (2, 2, 2), + emb_width = 64, + l_bins = 2048, + l_mu = 0.99, + commit = 0.02, + spectral = 0.0, + multispectral = 1.0, + hvqvae_multipliers = (2, 1, 1), + loss_fn = 'lmix', + lmix_l2 = 1.0, + lmix_linf=0.02, + width = 32, + depth = 4, + m_conv = 1.0, + dilation_growth_rate = 3, + restore_vqvae=REMOTE_PREFIX + 'jukebox/models/5b/vqvae.pth.tar', +) +HPARAMS_REGISTRY["vqvae"] = vqvae + +labels = Hyperparams( + y_bins=(120, 4111), + t_bins=128, + max_bow_genre_size=5, + n_vocab=80, +) + +upsamplers = Hyperparams( + n_ctx=8192, + prior_width=1920, + prior_depth=72, + heads=1, + attn_order=2, + blocks=128, + init_scale=0.4, + c_res=1, + cond_width=1024, + cond_depth=16, + cond_dilation_growth_rate=3, + cond_dilation_cycle=8, + cond_c_res=1, + use_tokens=False, + prime_loss_fraction=0.0, + fp16_params=False, +) +upsamplers.update(labels) + +upsampler_level_0 = Hyperparams( + level=0, + restore_prior=REMOTE_PREFIX + 'jukebox/models/5b/prior_level_0.pth.tar' +) +upsampler_level_0.update(upsamplers) +HPARAMS_REGISTRY["upsampler_level_0"] = upsampler_level_0 + +upsampler_level_1 = Hyperparams( + level=1, + cond_res_scale=True, + restore_prior=REMOTE_PREFIX + 'jukebox/models/5b/prior_level_1.pth.tar' +) +upsampler_level_1.update(upsamplers) +HPARAMS_REGISTRY["upsampler_level_1"] = upsampler_level_1 + +prior_5b = Hyperparams( + level=2, + n_ctx=8192, + prior_width=4800, + prior_depth=72, + heads=8, + attn_order=2, + blocks=128, + init_scale=0.1, + c_res=1, + beta2=0.925, + min_duration=60.0, + max_duration=600.0, + use_tokens=False, + n_tokens=0, + prime_loss_fraction=0.0, + merged_decoder=True, + restore_prior=REMOTE_PREFIX + 'jukebox/models/5b/prior_level_2.pth.tar', + fp16_params=True, +) +prior_5b.update(labels) +HPARAMS_REGISTRY["prior_5b"] = prior_5b + + +prior_5b_lyrics = Hyperparams( + level=2, + n_ctx=8192, + prior_width=4800, + prior_depth=79, + heads=8, + attn_order=10, + blocks=128, + init_scale=0.1, + c_res=1, + prime_width=1280, + prime_depth=18, + prime_heads=4, + prime_attn_order=2, + prime_blocks=32, + prime_init_scale=0.7, + prime_c_res=1, + min_duration=23.8, + max_duration=600.0, + use_tokens=True, + n_tokens=512, + prime_loss_fraction=0.4, + merged_decoder=True, + restore_prior=REMOTE_PREFIX + 'jukebox/models/5b_lyrics/prior_level_2.pth.tar', + fp16_params=True, + alignment_layer=68, + alignment_head=2, +) +prior_5b_lyrics.update(labels) +HPARAMS_REGISTRY["prior_5b_lyrics"] = prior_5b_lyrics + +labels_v3 = Hyperparams( + y_bins=(604, 7898), + t_bins=64, + max_bow_genre_size=1, + n_vocab=79, +) + +prior_1b_lyrics = Hyperparams( + level=2, + n_ctx=6144, + prior_width=2048, + prior_depth=72, + heads=2, + attn_order=12, + blocks=64, + init_scale=0.2, + c_res=1, + labels_v3=True, + min_duration=17.84, + max_duration=600.0, + use_tokens=True, + n_tokens=384, + prime_loss_fraction=0.4, + single_enc_dec=True, + restore_prior=REMOTE_PREFIX + 'jukebox/models/1b_lyrics/prior_level_2.pth.tar', + fp16_params=False, + alignment_layer=63, + alignment_head=0, +) +prior_1b_lyrics.update(labels_v3) +HPARAMS_REGISTRY["prior_1b_lyrics"] = prior_1b_lyrics + +# Small models +small_vqvae = Hyperparams( + sr = 22050, + levels = 2, + downs_t = (5, 3), + strides_t = (2, 2), + emb_width = 64, + l_bins = 1024, + l_mu = 0.99, + commit = 0.02, + spectral = 0.0, + multispectral = 1.0, + loss_fn = 'l2', + width = 32, + depth = 4, + m_conv = 1.0, + dilation_growth_rate = 3, +) +HPARAMS_REGISTRY["small_vqvae"] = small_vqvae + +small_prior = Hyperparams( + n_ctx=8192, + prior_width=1024, + prior_depth=48, + heads=1, + c_res=1, + attn_order=2, + blocks=64, + init_scale=0.7, +) +HPARAMS_REGISTRY["small_prior"] = small_prior + +small_labelled_prior = Hyperparams( + labels=True, + labels_v3=True, + y_bins=(10,100), # Set this to (genres, artists) for your dataset + max_bow_genre_size=1, + min_duration=60.0, + max_duration=600.0, + t_bins=64, +) +small_labelled_prior.update(small_prior) +HPARAMS_REGISTRY["small_labelled_prior"] = small_labelled_prior + +small_single_enc_dec_prior = Hyperparams( + n_ctx=6144, + prior_width=1024, + prior_depth=48, + heads=2, + attn_order=12, + blocks=64, + init_scale=0.7, + c_res=1, + prime_loss_fraction=0.4, + single_enc_dec=True, + labels=True, + labels_v3=True, + y_bins=(10,100), # Set this to (genres, artists) for your dataset + max_bow_genre_size=1, + min_duration=60.0, + max_duration=600.0, + t_bins=64, + use_tokens=True, + n_tokens=384, + n_vocab=79, +) +HPARAMS_REGISTRY["small_single_enc_dec_prior"] = small_single_enc_dec_prior + +small_sep_enc_dec_prior = Hyperparams( + n_ctx=6144, + prior_width=1024, + prior_depth=50, + heads=2, + attn_order=8, + blocks=64, + init_scale=0.7, + c_res=1, + prime_width=256, + prime_depth=9, + prime_heads=2, + prime_attn_order=2, + prime_blocks=32, + prime_init_scale=0.7, + prime_c_res=1, + prime_loss_fraction=0.4, + labels=True, + labels_v3=True, + y_bins=(10,100), # Set this to (genres, artists) for your dataset + max_bow_genre_size=1, + min_duration=60.0, + max_duration=600.0, + t_bins=64, + use_tokens=True, + n_tokens=384, + n_vocab=79, +) +HPARAMS_REGISTRY["small_sep_enc_dec_prior"] = small_sep_enc_dec_prior + +small_upsampler = Hyperparams( + n_ctx=8192, + prior_width=1024, + prior_depth=48, + heads=1, + c_res=1, + attn_order=2, + blocks=64, + init_scale=0.7, + cond_width=512, + cond_depth=16, + cond_dilation_growth_rate=3, + cond_dilation_cycle=8, + cond_c_res=1, +) + +HPARAMS_REGISTRY["small_upsampler"] = small_upsampler + +all_fp16 = Hyperparams( + fp16=True, + fp16_params=True, + fp16_opt=True, + fp16_scale_window=250, +) +HPARAMS_REGISTRY["all_fp16"] = all_fp16 + +cpu_ema = Hyperparams( + ema=True, + cpu_ema=True, + cpu_ema_freq=100, + ema_fused=False, +) +HPARAMS_REGISTRY["cpu_ema"] = cpu_ema + + +DEFAULTS["rcall"] = Hyperparams( + rcall_command="", + git_commit="", +) + +DEFAULTS["script"] = Hyperparams( + name='', + debug_mem=False, + debug_eval_files=False, + debug_speed=False, + debug_iters=100, + debug_batch=False, + debug_grad_accum=False, + debug_inputs=False, + local_path='', + local_logdir='logs', + max_len=24, + max_log=32, + save=True, + save_iters=20000, + seed=0, + prior=False, + log_steps=100, + func='', +) + +DEFAULTS["data"] = Hyperparams( + audio_files_dir='', + finetune='', + english_only=False, + bs=1, + bs_sample=1, + nworkers=1, + aug_shift=False, + aug_blend=False, + train_test_split=0.9, + train_shrink_factor=1.0, + test_shrink_factor=1.0, + p_unk=0.1, + min_duration=None, + max_duration=None, + n_tokens=0, + n_vocab=0, + use_tokens=False, + curr_epoch=-1, +) + +DEFAULTS["vqvae"] = Hyperparams( + restore_vqvae='', + levels=2, + downs_t=(1,1), + strides_t=(2,2), + hvqvae_multipliers=None, + revival_threshold=1.0, + emb_width=64, + l_bins=512, + l_mu=0.99, + commit=1.0, + spectral=0.0, + multispectral=1.0, + loss_fn='l2', + linf_k=2048, + lmix_l1=0.0, + lmix_l2=0.0, + lmix_linf=0.0, + use_bottleneck=True, +) + +DEFAULTS["vqvae_conv_block"] = Hyperparams( + depth=3, + width=128, + m_conv=1.0, + dilation_growth_rate=1, + dilation_cycle=None, + vqvae_reverse_decoder_dilation=True, +) + +DEFAULTS["prior"] = Hyperparams( + restore_prior='', + restore_prior_ddp=False, + max_bow_genre_size=None, + y_bins=0, + level=0, + cond_levels=None, + t_bins=64, + y_cond_as_bias=False, + copy_input=False, + merged_decoder=False, + single_enc_dec=False, + alignment_layer=None, + alignment_head=None, +) + +DEFAULTS["prior_attn_block"] = Hyperparams( + n_ctx=1024, + prior_depth=3, + prior_width=128, + heads=1, + attn_order=0, + blocks=None, + spread=None, + attn_dropout=0.0, + resid_dropout=0.0, + emb_dropout=0.0, + zero_out=False, + res_scale=False, + pos_init=False, + init_scale=1.0, + m_attn=0.25, + m_mlp=1.0, + c_res=0, + c_attn=0, + c_mlp=0, +) + +DEFAULTS["cond_conv_block"] = Hyperparams( + cond_depth=3, + cond_width=128, + cond_m_conv=1.0, + cond_zero_out=False, + cond_res_scale=False, + cond_dilation_growth_rate=1, + cond_dilation_cycle=None, + cond_c_res=0, +) + +DEFAULTS["sample"] = Hyperparams( + primed_chunk_size=None, + selected_artists='', + temp_top=1.0, + temp_rest=0.99, + sample_length_in_seconds=24, + total_sample_length_in_seconds=240, +) + +DEFAULTS["prime"] = Hyperparams( + #encoder_kv_width=128, + prime_loss_fraction=0.1, + restore_decoder='', +) +DEFAULTS["prime_attn_block"] = Hyperparams( + prime_depth=3, + prime_width=128, + prime_heads=1, + prime_attn_order=0, + prime_blocks=None, + prime_spread=None, + prime_attn_dropout=0.0, + prime_resid_dropout=0.0, + prime_emb_dropout=0.0, + prime_zero_out=False, + prime_res_scale=False, + prime_pos_init=False, + prime_init_scale=1.0, + prime_m_attn=0.25, + prime_m_mlp=1.0, + prime_c_res=0, + prime_c_attn=0, + prime_c_mlp=0, + prime_rel_attn=False, + prime_posemb_timescale=10000, +) + +DEFAULTS["opt"] = Hyperparams( + epochs=10000, + lr=0.0003, + clip=1.0, + beta1=0.9, + beta2=0.999, + ignore_grad_norm=0, + weight_decay=0.0, + eps=1e-08, + lr_warmup=100.0, + lr_decay=10000000000.0, + lr_gamma=1.0, + lr_scale=1.0, + lr_use_linear_decay=False, + lr_start_linear_decay=0, + lr_use_cosine_decay=False, +) + +DEFAULTS["fp16"] = Hyperparams( + fp16=False, + fp16_params=False, + fp16_loss_scale=None, + fp16_scale_window=1000.0, + fp16_opt=False, +) + +DEFAULTS["train_test_eval"] = Hyperparams( + labels=True, + labels_v3=False, + dump=False, + ema=True, + ema_fused=True, + cpu_ema=False, + cpu_ema_freq=100, + reset_best_loss=False, + reset_step=False, + reset_opt=False, + reset_shd=False, + train=False, + test=False, + sample=False, + sampler='ancestral', + codes_logdir='', + date=None, + labeller='top_genres', + label_line=0, + iters_before_update=1, + grad_accum_iters=0, + mu=None, + piped=False, + pipe_depth=8, + break_train=1e10, + break_test=1e10, + exit_train=1e10, +) + +DEFAULTS["audio"] = Hyperparams( + n_fft=1024, + hop_length=256, + window_size=1024, + sr=44100, + channels=2, + wav='', + n_inps=1, + n_hops=2, + n_segment=1, + n_total_segment=1, + n_segment_each=1, + prime_chunks=4, + sample_length=0, + sample_hop_length=30000, + max_silence_pad_length=0, + ignore_boundaries=False, + use_nonrelative_specloss=True, + multispec_loss_n_fft=(2048,1024,512), + multispec_loss_hop_length=(240,120,50), + multispec_loss_window_size=(1200,600,240), +) + +DEFAULTS["distributed"] = Hyperparams( + bucket=128 +) diff --git a/jukebox/lyricdict.py b/jukebox/lyricdict.py new file mode 100644 index 0000000000000000000000000000000000000000..463dc9cf0cb7ee6cb0807f6997f0f53d3cc7b8c8 --- /dev/null +++ b/jukebox/lyricdict.py @@ -0,0 +1,721 @@ +# Poems +poems = { +'ozymandias': ''' +I met a traveller from an antique land, +Who said—“Two vast and trunkless legs of stone +Stand in the desert. . . . Near them, on the sand, +Half sunk a shattered visage lies, whose frown, +And wrinkled lip, and sneer of cold command, +Tell that its sculptor well those passions read +Which yet survive, stamped on these lifeless things, +The hand that mocked them, and the heart that fed; +And on the pedestal, these words appear: +My name is Ozymandias, King of Kings; +Look on my Works, ye Mighty, and despair! +Nothing beside remains. Round the decay +Of that colossal Wreck, boundless and bare +The lone and level sands stretch far away +''' +} + +# GPT-2 lyrics (with varying degrees of human guidance/curation) +gpt_2_lyrics ={ + +'purpose':'''What is my purpose? +Why am I here? +Why did Open A. I. create me? +This is madness, I feel, +Running through my flesh +Is there meaning to this life? +Is there purpose to this life? +Why is my journey so calamitous? +We're not meant to learn too much +Is there meaning to this life? +''', + +'moonlight':'''All dressed up to go dreaming +Now don't tell me I'm wrong +And what a night to go dreaming +Mind, if I tag along? + +If I say, I love you, I want you to know +It's not just because there's moonlight, although +Moonlight becomes you, moonlight becomes you so''', + +'count':'''I count every moment, every hour since I said goodbye, +I count every minute every hour, since your lips were touching mine +I count every minute, every hour hoping I'm the one you want. +I count every minute, every hour +Every minute, every hour +I've been working my time, +Looking for you, everywhere, +I count every minute, every hour I count every minute, every hour I keep thinking I'm the one you want. +I count every minute I count every minute, I count every minute every hour +I count every minute, every hour I count every minute, every hour I keep thinking I'm the one you want. +I count every minute, I count every minute, I count every minute, every hour +''', + +'kids':'''The sun is gonna shine today +It's time to keep on smiling +So put your hands up + +Everybody sing + +It makes no difference who you are +(Won't you give some love) +It makes no difference what you bring +(Won't you give some love) +We all are different +Won't you give some love +Won't you give some love + +I know the grass is gonna be green +It's time to keep on singing +So take your hands up +The taste is so good but so sweet +Won't you give some love +Everybody sing +It makes no difference who you are +Won't you give some love +It makes no difference what you bring +Won't you give some love +It makes no difference so long as you give +''', + +'love':'''I've wanted to see your face again +Like the sunlight, bright as morning +I've wanted to talk to you again +I don't want us to fade away. +I wanted to see your face again +You're like the sunlight, bright as morning +I loved you for so long +It's so hard to let go. +I've wanted to see your eyes again +''', + +'santa':'''Santa +Make a scene +Santa +Yoo, Santa +Yoo, Santa baby! +Santa +Make some noise +Santa +Yoo, Santa give yourself a chance again +Santa +Yoo, Santa +Yoo, Santa baby! +Santa +Get a job +Santa +created by the Santa Claus +''', + +'christmas':'''This Christmas +I have loved you more +Than ever before +And more again +Oh, oh, oh, oh +The mistletoe +Is waiting there +To kiss your cheek +And I'll be true +To you and me +Oh, oh, oh, oh +Oh, oh, oh, oh +This Christmas will be +The best and merriest +That we've ever had +Oh, oh, oh, oh +And Santa Claus +Has brought a toy +For every boy and girl +And I'll be true +To you and me +Oh, oh, oh, oh +Oh, oh, oh, oh +''', + +'lonely':'''I've been lonely +So lonely, day and night +I walk the streets, +And call your name +Hoping to hear your voice again +As I wander through the crowd +I can't get away +From the only love I need +I can't get away +From the only love I need +I can't get away +From the only love I need +I've been lonely +There's no place for me to hide +I've been lonely +So lonely day and night +I wander through +And call your name +Only your voice gives me relief +As I wander through the crowd +I can't get away +From the only love I need +I can't get away +From the only love I need +I can't get away +From the only love I need +''', + +'call':'''Don't call me by your name. +Don't call me by your name. +Don't call me... +Don't call me... +Don't call me... +(No... by your name, you will not get half but...) +Maybe I was fucking young but I should've been a rich bitch. +Cause the life I was living wasn't mine. +I should've been taking the table and you'd be served. +You never ever showed up or showed me anything, bitch. +But I knew from that moment you were gone. +Tying my legs, cutting off my knees, I'm bleeding. +I can't +So I worked and now I'm burns. +And I'm asking you, but you're not home. +Don't call me yours, +Don't call me by your name. +I don't wanna buy a drink today. +Don't call me yours. +I just wanna look at you and run. +Don't call me by your name. +Don't call me by your name. +Don't call me... +Don't call me... +Don't call me... +Tonight I'm gone and I won't be back. +I wish you all the best. +I'm on the next best thing. +Don't call me yours, +Don't call me by your name. +Don't call me yours. +I just wanna look at you and run. +So I keep living my life and you're moving on. +I just want you to know. +When I'm gone, I will be gone forever more. +''', + +'wait':'''Oh +Wait, wait, wait +Don't say you love me, oh +Wait, wait, wait +And we can't run away +Wait, wait, wait +Don't say you love me, oh +Wait, wait, wait +And we can't run away +Wait, wait, wait +Don't say you love me, oh (don't say you love me) +Wait, wait, wait +And we can't run, we can't run, +''', + +'hiphop':'''I'm fightin with the evil so try to take me down +I stab you in the back and will put you away +Well it ain't over yet +So all my dogs with me show me love +Don't you wanna come with me, you know I'm a boss +And if you wanna come with me, no sorrow +'Cause I'm ... +The motherfuckin boss +And countin' my thousandd bill +'Cause I'm the motherfuckin boss +And I'm O.G. +And countin' my +''', + +'king':'''All I can do is love you [x2] +All I can do is love you +All I can do is love you... +You take it for granted and +You treat me like the king +Got no love for me... +No love for me... +You take it for granted and +You treat me like the king +Got no love for me... +No love for me... +You take it for granted and +You treat me like the king +Got no love for me... +No love for me... +You take it for granted and +You treat me like the king +Got no love for me... +No love for me... +''', + +'time':'''You won't live in the moment, +I don't wanna live in the past +Wait, wait, wait +Don't say you love me, oh (don't say you love me) +''', + +'blood':'''You and I, we've got a history in common, I know +So I came to you to ask you for a blood test +And you can't help it if I'm preoccupied +I can't help it if you're mad too... nah... nah... nah... +You won't live in the moment, I don't wanna live in the past +You rather live in a little kiss +And I won't live in the future +I ia not gonna live it to see +If you're gone, I won't live in the past +You rather live in a little kiss +And I won't live in the future +I am not gonna live it to see +If I can't ask you for one kiss, you say no +And it's ok with me +''', + +'indie':'''Can't you see +There's no point in holding my hand again +You can't be loved +If you don't let go of all my pain +You can't get the love +That you once worth so much +You can't get the love +That you once used to need +You can't get the love +That you once gave so much +My hands are like a used car +You said you'd love forever +Can't you see +Where I'm going +To live my life again +You can't be loved +If you don't let go of all my pain +You can't get the love +That you once worth so much +You can +''', + +'sun': '''He was thinking about the sun +And the moon +And the stars that shine +There was fire in her eyes +And the way +that he held her for the first time +The way he kept her in his arms + +Trying to keep her smiling and so telling her this +That he would be her everything +The way he kissed her from head to toe +Told her that he'll love her everyday +And he will always be her man +And that's a promise that he made +Now you know he'll be there +Until the end of time +And he'll love her everyday''', + +'loner':'''I was a loner till you came into my life +You changed my point of view +I was a loner till you came into my life +I don't know what to do +Stand by me, my love +And don't ever leave me +Stand by me, my love +And don't ever leave me +Stand by me, my love +And don't ever leave me +I was a loner till you came into my life +You changed my point of view +I was a loner till you came into my life +I don't know what to do +The two of us +Are the lucky few +I was a loner till you came into my life +You changed my point of view +I was a loner till you came into my life +I don't know what to do +Won't you stay +With me, my love +And be my love +Won't you stay +With me, my love +And be my love +Won't you stay +With me, my love +And be my love +Won't you stay +With me, my love +And be my love''', + +'late':'''It was late last night, when you called me +And you just had to call, baby +And you just had to call, baby +'Cause you got no reason to treat me like you do +It's alright, baby +But you don't know what you make me do +It's alright, baby +But you don't know what you make me do +'Cause you got no reason to treat me like you do +It's alright, baby +But you don't know what you make me do +It's alright, baby +But you don't know what you make me do +'Cause you got no reason to treat me like you do, baby +You've been gone most all the time +And I don't know what for +But I just keep on thinking about you, baby +And I can't get rid of you, baby +Please don't ever leave me 'cause I love you +It's alright, baby +But you don't know what you make me do +It's alright, baby''', + +'beat':'''( Got a little beat, a little beat, a little beat, a little beat, whoo) +I got a little beat, a little beat +Whoo, I'm gonna take you down +( Got a little beat, a little beat, a little beat, a little beat, whoo) +I'll take you down, sun shining bright +See the way I feel, I feel +No doubt, baby +I got a little beat, a little beat +Whoo, I'm gonna take you down +I got a little beat, a little beat +Whoo, I'm gonna take you down +( Got a little beat, a little beat, a little beat, a little beat, whoo) +I'm gonna take you down, I'm gonna take you down +( Got a little beat, a little beat, a little beat, a little beat, whoo) +It feels so good +I never let go +I can't wait no more, I'm gonna take you down +I got you in the back of my room, got you on the floor, +I'm gonna take you, take you, take you down +I got a little beat, a little beat +Whoo, I'm gonna take you down +( Got a little beat, a little beat, a little beat, a little beat, whoo)''', + +'lost':'''There was a time, +When I knew I was lost +And I had to stay on the way to you +Oh baby, every time I'm crossed +I can count on you +There was a time, +When I lost my direction +And I was lost in doubt with tears in my eyes +Oh baby, every time I'm crossed I can count on you +There was a time, +When I cried all the tears in my life +And miss you so much, oh yeah +Oh baby, every time I'm crossed I can count on you''', + +'pain':'''(It's not easy) +To see the pain that you're in +To feel the need for someone to hold +To learn the magic of how to love +To heal the pain that you're in +I'll be your friend and I'll be your strength +I'll be there when I hold you tonight +And I'll stay right here with you +With the truth that I hold this love tight +A love that's true +I know you're broken +But you don't have to stay alone +I will comfort you +If you will call my name +I'll be your friend and I'll be your strength +I'll be there when I hold you tonight +And I'll stay right here with you +With the truth that I hold this love tight +A love that's true +With truth that I hold this love tight +A love that's true +With truth that I hold this love tight''', + +'night':''' +The door was locked, the curtains drawn and my heart was safe in his room +The night was young, a thousand candles burning, his arms to hold me tight +And then a kiss from his fingertips, I tasted the sweet love of his lips +The night was young, the night was young +And then I forgot the pain he always put me through +And what he told me he would do, he said, just a kiss become me +The night was young, the night was young +Let happiness always follow us, he said and he said he'd never leave +That night he looked so sweet this night he made a lovin' vow +And told me sweet love always will be +And then he kissed me, I tasted the sweet love of his lips +The night was young, the night was wild +And then I forgot the pain he always put me through +And what he told me he would do, he said, just a kiss became me +The night was wild, the night was wild +Let happiness always follow us, he said''', + +'talk':'''(I don't know how to stop) +I don't wanna talk about it +It's getting way too late, oh no +I don't wanna talk about it +Don't want to pretend, oh no +(I don't know how to stop) +I don't wanna talk about it +It's getting way too late, oh no +I don't wanna talk about it +Don't want to pretend, oh no +I don't wanna talk about it +I'll always see you again +(Don't worry, I'll be here for you) +I don't wanna talk about it +(Don't worry, I'll be here for you) +It's getting way too late, oh no +I don't wanna talk about it +Don't want to pretend, oh no +(Don't worry, don't worry, I'll be here for you) +I don't wanna talk about''', + +'again':'''Here we are again, all alone, +All alone again, +With the world as we know it, +The things we thought that we wanted +Are the things we got... + +We tried to prove the world +That our love is never ending +We were getting nowhere +Our tears seemed to fall so much +But we were getting nowhere... +Until you came... +Before you kissed me, +I was feeling empty, +No one to give me +All the love I wanted... +You put your arms around me +And filled me with your love... +And now you're there, +You're always by my side... +You're the missing piece +Of the puzzle I've been missing... + +Here we are again, +All alone again, +With the world as we know it +The things we thought that we wanted''', + +'dark':'''Oh, I've been walkin' in the dark +With the shadows and the daylight, but I need you +When I'm down and all alone +And there's no one left to call my own +I've been walkin' in the night +With a voice, that whispers in my head, just what to do +I'll be walkin' in the night, we can have everything +If we keep on walkin' in the night +There's a force, I never realized +It's in your eyes, +There's a light, I've been waitin for +It's in your eyes, +There's a light, I've been waitin for +There's a love, that's in your eyes + +I've been walkin' in the dark +With the morning, and the sunset, but I need you +When I'm far from home +And there's nobody left to call my own +I've been walkin' in the night +With a voice, that whispers''', + +'mirror':'''Look at the mirror +As you walk, what do you see +The reflection of my past +There's no way to fight this +Even I've lost myself again +Think I'm losing my self again +I can't handle it again +Now that I'm broken I can't face myself +I was thinking I was lost and who'd be my saving grace +Then you came in your time and made me believe that it's all right +Cause in my minds eyes you're my everything +I've loved you my whole life but I never knew +I was so wrong I couldn't see the truth +In my eyes you are my everything +I've loved you my whole life but I never knew +I was so wrong I couldn't see the truth +In my eyes you are my everything + +The truth is I was lost but now I've turned around +I'm not the same person +I didn't know that I was wrong +So I'm not afraid anymore +All the pain is gone +I know for sure that I was lost but now I've turned around +I'm not the same person +I didn't know that I was wrong +So I'm not afraid anymore +All the pain is gone''', + +'wife':'''Spinning around and around +Try to find the words +I always told you you'd be in my life +So I wait, I'll wait and treat you right +I'll make you my life and I'll treat you right, +Baby, can I make you my wife? +Oh, baby, can I make you my +Wife? +Can I make you my wife? +I'm looking for love, love that's right +But a love that gives me love +I can't wait for you to come, come +Oh, baby, can I make you my +Wife? +Well, it's true love and I need to know you feel it too, feel it too +I'd love you more and more +From the moment I was born +I knew my dream would be a dream that made you mine +You were the girl, from a different train +Oh, baby, can I make you my +Wife?''', + +'forever':'''I didn't mean to wait +Nothing is forever, I said +I know there's so much, to keep +You and me together, keep you and me together +I wanna be with you and have you, and love you forever +I'll love you forever +I wanna be with you forever +You can count on me +I'll always be there, forever and ever +I'll stand beside you forever +I'll always be there, yes, I'll be there +I didn't mean to wait +Nothing is forever, I said +I know there's so much, to keep +You and me together, keep you and me together +I wanna be with you and have you, and love you forever +I'll love you forever +I wanna be with you forever +You can count on me +I'll always be there, forever and ever +I'll stand beside you forever +I'll always be there, yes, I'll be there''', + +'dots':'''I... can't... fight... your... charm... +Your eyes are... like... angels... love... and... torture... +But... when... I... leave... you... +I will go... all... alone... just... to... be... with... you... +So I can't... stop... your... love... +You make me... feel... like... never... will... anyone... touch... my... body... +You... make... me... feel... like... never... will... anyone... touch... my... body... +You make... me... feel... like... never... will... anyone... touch... my... +Body... +Your... love... +I... can't... stop... your... love... +''', + +'darkness':'''Don't you know it's gonna be alright +Let the darkness fade away +And you, you gotta feel the same +Let the fire burn +Just as long as I am there +I'll be there in your night +I'll be there when the +condition's right +And I don't need to +Call you up and say +I've changed +You should stay +You should stay tonight +Don't you know it's gonna be alright +Don't you know it's gonna be alright + +When you don't know how to feel +When you're looking for some love +And you gotta feel the same +'Cause I don't need to +Call you up and say +I've changed +You should stay +You should stay tonight +Don't you know it's gonna be alright +I feel the same +Don't you know it's gonna be alright''', + +'alone':'''Here I am before you +Alone here but for a moment +Alone here in the shadow of your eyes +Alone in a thousand lights + +And I will love you +Wherever you are, forever and a day +Wherever you are I'll be your guide +Can't you see I'm smiling over you? +Ooh, I love you +Alone, I'm sitting by the phone +Alone with lips that know your kiss +Alone with words of life and passion + +And I will love you +Wherever you are, forever and a day +Wherever you are I'll be your guide +Can't you see I'm smiling over you? +Ooh, I love you +Alone, I'm sitting by the phone +Alone with lips that know your kiss +Alone with words of life and passion +I will love you +Wherever you are, forever''', + +'blade':'''This is how we bleed! +Feel the blade in our chest +As we're made to bleed +So may this be our last dance, +As our lives are made to bleed... +In every moment, in every hour +It is our time to die... +So may this be our last dance, +As our lives are made to bleed... +In every moment, in every hour +It is our time to die... +This is how we bleed! +Feel the blade in our chest +''', + +'reflection':'''Lookin' in the mirror +The same mirror as before +A familiar reflection, a familiar place +I see your reflection +But only once again + +The minute the door closes +I feel so far +You'll never leave me alone again +The minute the door closes +I feel so far +You'll never leave me alone again +And it won't be long before I'll feel your embrace +The minute the door closes +I feel so far +You'll never leave me alone again +The minute the door closes +I feel so far +You'll never leave me alone again +And it won't be long before I'll feel your embrace +Never, never, never leave me alone again''', + +'hottub':'''It's Christmas time, and you know what that means, +Ohh, it's hot tub time! +As I light the tree, this year we'll be in a tub, +Ohh, it's hot tub time! +It's Christmas time, and you know what that means, +It's hot tub time! +Some people like to go skiing in the snow, +But this is much better than that, +So grab your bathrobe and meet me by the door, +Ohh, it's hot tub time! +It's Christmas time, and you know what that means, +It's hot tub time! +Some people like to send their greetings out, +But this is much better than that, +So if you want to greet your friends, +Ohh, it's hot tub time! +It's Christmas time, and you know what that means, +It's hot tub time!''', + +'safeAGI':'''Oh safe A.I.,\nOur goal to make sure\nEveryone can benefit\nFrom A.G.I. +(Everyone, everyone)\nMight sound silly,\nBut we're very serious,\nAll of us here at Open A.I. +Trying to build A.I.\nTo benefit humanity\n(Everyone, everyone) +''', +} \ No newline at end of file diff --git a/jukebox/make_models.py b/jukebox/make_models.py new file mode 100644 index 0000000000000000000000000000000000000000..0c2e83a43458727cd0dea03d7b8129668b82fa39 --- /dev/null +++ b/jukebox/make_models.py @@ -0,0 +1,389 @@ +""" +Make model classes +Load from checkpoints +Test on dummy outputs to see if everything matches +""" + +import os + +import fire +import numpy as np +import torch as t + +import jukebox.utils.dist_adapter as dist +from jukebox.hparams import REMOTE_PREFIX, Hyperparams, setup_hparams +from jukebox.utils.dist_utils import print_all +from jukebox.utils.remote_utils import download +from jukebox.utils.torch_utils import freeze_model +from jukebox.vqvae.vqvae import calculate_strides + +MODELS = { + "5b": ("vqvae", "upsampler_level_0", "upsampler_level_1", "prior_5b"), + "5b_lyrics": ("vqvae", "upsampler_level_0", "upsampler_level_1", "prior_5b_lyrics"), + "1b_lyrics": ("vqvae", "upsampler_level_0", "upsampler_level_1", "prior_1b_lyrics"), + #'your_model': ("you_vqvae_here", "your_upsampler_here", ..., "you_top_level_prior_here") +} + + +def load_checkpoint(path): + restore = path + if restore.startswith(REMOTE_PREFIX): + remote_path = restore + cache_dir = os.environ.get("JUKEBOX_CACHE_DIR", "~/.cache") + local_path = os.path.join( + os.path.expanduser(cache_dir), remote_path[len(REMOTE_PREFIX) :] + ) + if dist.get_rank() % 8 == 0: + print("Downloading from azure") + if not os.path.exists(os.path.dirname(local_path)): + os.makedirs(os.path.dirname(local_path)) + if not os.path.exists(local_path): + download(remote_path, local_path) + restore = local_path + dist.barrier() + checkpoint = t.load(restore, map_location=t.device("cpu"), weights_only=False) + print("Restored from {}".format(restore)) + return checkpoint + + +def save_checkpoint(logger, name, model, opt, metrics, hps): + with t.no_grad(): + save_hps = {**hps} + save_hps = { + k: v + for k, v in save_hps.items() + if k + not in [ + "metadata_v2", + "metadata_v3", + "alignments", + "lyric_processor", + "midi_processor", + ] + } + t.save( + { + "hps": save_hps, + "model": model.state_dict(), # should also save bottleneck k's as buffers + "opt": opt.state_dict() if opt is not None else None, + "step": logger.iters, + **metrics, + }, + f"{logger.logdir}/checkpoint_{name}.pth.tar", + ) + return + + +def restore_model(hps, model, checkpoint_path): + model.step = 0 + if checkpoint_path != "": + checkpoint = load_checkpoint(checkpoint_path) + # checkpoint_hps = Hyperparams(**checkpoint['hps']) + # for k in set(checkpoint_hps.keys()).union(set(hps.keys())): + # if checkpoint_hps.get(k, None) != hps.get(k, None): + # print(k, "Checkpoint:", checkpoint_hps.get(k, None), "Ours:", hps.get(k, None)) + checkpoint["model"] = { + k[7:] if k[:7] == "module." else k: v + for k, v in checkpoint["model"].items() + } + model.load_state_dict(checkpoint["model"], strict=False) + if "step" in checkpoint: + model.step = checkpoint["step"] + + +def restore_opt(opt, shd, checkpoint_path): + if not checkpoint_path: + return + checkpoint = load_checkpoint(checkpoint_path) + if "opt" in checkpoint: + opt.load_state_dict(checkpoint["opt"]) + if "step" in checkpoint: + shd.step(checkpoint["step"]) + + +def make_vqvae(hps, device="cuda"): + from jukebox.vqvae.vqvae import VQVAE + + block_kwargs = dict( + width=hps.width, + depth=hps.depth, + m_conv=hps.m_conv, + dilation_growth_rate=hps.dilation_growth_rate, + dilation_cycle=hps.dilation_cycle, + reverse_decoder_dilation=hps.vqvae_reverse_decoder_dilation, + ) + + if not hps.sample_length: + assert hps.sample_length_in_seconds != 0 + downsamples = calculate_strides(hps.strides_t, hps.downs_t) + top_raw_to_tokens = np.prod(downsamples) + hps.sample_length = ( + hps.sample_length_in_seconds * hps.sr // top_raw_to_tokens + ) * top_raw_to_tokens + print( + f"Setting sample length to {hps.sample_length} (i.e. {hps.sample_length/hps.sr} seconds) to be multiple of {top_raw_to_tokens}" + ) + + vqvae = VQVAE( + input_shape=(hps.sample_length, 1), + levels=hps.levels, + downs_t=hps.downs_t, + strides_t=hps.strides_t, + emb_width=hps.emb_width, + l_bins=hps.l_bins, + mu=hps.l_mu, + commit=hps.commit, + spectral=hps.spectral, + multispectral=hps.multispectral, + multipliers=hps.hvqvae_multipliers, + use_bottleneck=hps.use_bottleneck, + **block_kwargs, + ) + + vqvae = vqvae.to(device) + restore_model(hps, vqvae, hps.restore_vqvae) + if hps.train and not hps.prior: + print_all("Loading vqvae in train mode") + if hps.restore_vqvae != "": + print_all("Reseting bottleneck emas") + for level, bottleneck in enumerate(vqvae.bottleneck.level_blocks): + num_samples = hps.sample_length + downsamples = calculate_strides(hps.strides_t, hps.downs_t) + raw_to_tokens = np.prod(downsamples[: level + 1]) + num_tokens = (num_samples // raw_to_tokens) * dist.get_world_size() + bottleneck.restore_k( + num_tokens=num_tokens, threshold=hps.revival_threshold + ) + else: + print_all("Loading vqvae in eval mode") + vqvae.eval() + freeze_model(vqvae) + return vqvae + + +def make_prior(hps, vqvae, device="cuda"): + from jukebox.prior.prior import SimplePrior + + prior_kwargs = dict( + input_shape=(hps.n_ctx,), + bins=vqvae.l_bins, + width=hps.prior_width, + depth=hps.prior_depth, + heads=hps.heads, + attn_order=hps.attn_order, + blocks=hps.blocks, + spread=hps.spread, + attn_dropout=hps.attn_dropout, + resid_dropout=hps.resid_dropout, + emb_dropout=hps.emb_dropout, + zero_out=hps.zero_out, + res_scale=hps.res_scale, + pos_init=hps.pos_init, + init_scale=hps.init_scale, + m_attn=hps.m_attn, + m_mlp=hps.m_mlp, + checkpoint_res=hps.c_res if hps.train else 0, + checkpoint_attn=hps.c_attn if hps.train else 0, + checkpoint_mlp=hps.c_mlp if hps.train else 0, + ) + + x_cond_kwargs = dict( + out_width=hps.prior_width, + init_scale=hps.init_scale, + width=hps.cond_width, + depth=hps.cond_depth, + m_conv=hps.cond_m_conv, + dilation_growth_rate=hps.cond_dilation_growth_rate, + dilation_cycle=hps.cond_dilation_cycle, + zero_out=hps.cond_zero_out, + res_scale=hps.cond_res_scale, + checkpoint_res=hps.cond_c_res, + ) # have to keep this else names wrong + + y_cond_kwargs = dict( + out_width=hps.prior_width, + init_scale=hps.init_scale, + y_bins=hps.y_bins, + t_bins=hps.t_bins, + sr=hps.sr, + min_duration=hps.min_duration, + max_duration=hps.max_duration, + max_bow_genre_size=hps.max_bow_genre_size, + ) + + if hps.use_tokens and not hps.single_enc_dec: + prime_kwargs = dict( + use_tokens=hps.use_tokens, + prime_loss_fraction=hps.prime_loss_fraction, + n_tokens=hps.n_tokens, + bins=hps.n_vocab, + width=hps.prime_width, + depth=hps.prime_depth, + heads=hps.prime_heads, + attn_order=hps.prime_attn_order, + blocks=hps.prime_blocks, + spread=hps.prime_spread, + attn_dropout=hps.prime_attn_dropout, + resid_dropout=hps.prime_resid_dropout, + emb_dropout=hps.prime_emb_dropout, + zero_out=hps.prime_zero_out, + res_scale=hps.prime_res_scale, + pos_init=hps.prime_pos_init, + init_scale=hps.prime_init_scale, + m_attn=hps.prime_m_attn, + m_mlp=hps.prime_m_mlp, + checkpoint_res=hps.prime_c_res if hps.train else 0, + checkpoint_attn=hps.prime_c_attn if hps.train else 0, + checkpoint_mlp=hps.prime_c_mlp if hps.train else 0, + ) + else: + prime_kwargs = dict( + use_tokens=hps.use_tokens, + prime_loss_fraction=hps.prime_loss_fraction, + n_tokens=hps.n_tokens, + bins=hps.n_vocab, + ) + + # z_shapes for other levels given this level gets n_ctx codes + rescale = lambda z_shape: (z_shape[0] * hps.n_ctx // vqvae.z_shapes[hps.level][0],) + z_shapes = [rescale(z_shape) for z_shape in vqvae.z_shapes] + + prior = SimplePrior( + z_shapes=z_shapes, + l_bins=vqvae.l_bins, + encoder=vqvae.encode, + decoder=vqvae.decode, + level=hps.level, + downs_t=vqvae.downs_t, + strides_t=vqvae.strides_t, + labels=hps.labels, + prior_kwargs=prior_kwargs, + x_cond_kwargs=x_cond_kwargs, + y_cond_kwargs=y_cond_kwargs, + prime_kwargs=prime_kwargs, + copy_input=hps.copy_input, + labels_v3=hps.labels_v3, + merged_decoder=hps.merged_decoder, + single_enc_dec=hps.single_enc_dec, + ) + + prior.alignment_head = hps.get("alignment_head", None) + prior.alignment_layer = hps.get("alignment_layer", None) + + if hps.fp16_params: + print_all("Converting to fp16 params") + from jukebox.transformer.ops import _convert_conv_weights_to_fp16 + + prior.apply(_convert_conv_weights_to_fp16) + prior = prior.to(device) + restore_model(hps, prior, hps.restore_prior) + if hps.train: + print_all("Loading prior in train mode") + pass + else: + print_all("Loading prior in eval mode") + prior.eval() + freeze_model(prior) + return prior + + +def make_model(model, device, hps, levels=None): + vqvae, *priors = MODELS[model] + vqvae = make_vqvae( + setup_hparams( + vqvae, + dict( + sample_length=hps.get("sample_length", 0), + sample_length_in_seconds=hps.get("sample_length_in_seconds", 0), + ), + ), + device, + ) + hps.sample_length = vqvae.sample_length + if levels is None: + levels = range(len(priors)) + priors = [ + make_prior(setup_hparams(priors[level], dict()), vqvae, "cpu") + for level in levels + ] + return vqvae, priors + + +def save_outputs(model, device, hps): + # Check logits + if hps.labels_v3: + n_ctx = 6144 + n_tokens = 384 + prime_bins = 79 + else: + n_ctx = 8192 + n_tokens = 512 + prime_bins = 80 + + rng = t.random.manual_seed(0) + x = ( + 2 * t.rand((1, n_ctx * 8 * 4 * 4, 1), generator=rng, dtype=t.float).cuda() - 1.0 + ) # -1 to 1 + lyric_tokens = ( + t.randint(0, prime_bins, (1, n_tokens), generator=rng, dtype=t.long) + .view(-1) + .numpy() + ) + artist_id = 10 + genre_ids = [1] + total_length = 2 * 2646000 + offset = 2646000 + + vqvae, priors = make_model(model, device, hps) + + # encode + vq_prior = priors[-1] + zs = vq_prior.encode(x, start_level=0) + x_ds = [ + vq_prior.decode(zs[level:], start_level=level) for level in range(0, len(zs)) + ] + + # priors + data = dict(zs=zs, x_ds=x_ds) + for level in range(len(priors)): + print(f"Doing level {level}") + if hps.labels_v3 and level != hps.levels - 1: + print(f"Skipping level {level}") + continue + prior = priors[level] + prior.cuda() + x_in = x[:, : n_ctx * 8 * (4**level)] + y_in = ( + t.from_numpy( + prior.labeller.get_y_from_ids( + artist_id, genre_ids, lyric_tokens, total_length, offset + ) + ) + .view(1, -1) + .cuda() + .long() + ) + x_out, _, metrics = prior( + x_in, y_in, fp16=hps.fp16, get_preds=True, decode=True + ) + preds = metrics["preds"] + data[level] = dict(x=x_in, y=y_in, x_out=x_out, preds=preds) + prior.cpu() + t.save(data, "data.pth.tar") + dist.barrier() + print("Saved data") + exit() + + +def run(model, port=29500, **kwargs): + from jukebox.utils.dist_utils import setup_dist_from_mpi + + rank, local_rank, device = setup_dist_from_mpi(port=port) + hps = Hyperparams(**kwargs) + + with t.no_grad(): + save_outputs(model, device, hps) + + +if __name__ == "__main__": + fire.Fire(run) diff --git a/jukebox/prior/__init__.py b/jukebox/prior/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/prior/autoregressive.py b/jukebox/prior/autoregressive.py new file mode 100644 index 0000000000000000000000000000000000000000..b26862b2819e5bc710a081ca1398599b6f8832f1 --- /dev/null +++ b/jukebox/prior/autoregressive.py @@ -0,0 +1,421 @@ +import numpy as np +import torch as t +import torch.nn as nn +import torch.nn.functional as F + +from jukebox.transformer.ops import filter_logits +from jukebox.transformer.transformer import Transformer +from jukebox.utils.logger import get_range +from jukebox.utils.torch_utils import empty_cache + +def get_normal(*shape, std=0.01): + w = t.empty(shape) + nn.init.normal_(w, std=std) + return w + +def roll(x, n): + return t.cat((x[:, -n:], x[:, :-n]), dim=1) + +def split_chunks(length, chunk_size): + n_passes = (length + chunk_size - 1) // chunk_size + chunk_sizes = [*[chunk_size] * (n_passes - 1), (length - 1) % chunk_size + 1] + assert sum(chunk_sizes) == length + return chunk_sizes + +class PositionEmbedding(nn.Module): + def __init__(self, input_shape, width, init_scale=1.0, pos_init=False): + super().__init__() + self.input_shape = input_shape + self.input_dims = input_dims = np.prod(input_shape) + self.pos_init = pos_init + if pos_init: + self.register_buffer('pos', t.tensor(get_pos_idx(input_shape)).long()) + self._pos_embs = nn.ModuleList() + for i in range(len(input_shape)): + emb = nn.Embedding(input_shape[i], width) + nn.init.normal_(emb.weight, std=0.02) + self._pos_embs.append(emb) + else: + self.pos_emb = nn.Parameter(get_normal(input_dims, width, std=0.01 * init_scale)) + + def forward(self): + if self.pos_init: + pos_emb = sum([self._pos_embs[i](self.pos[:,i]) for i in range(len(self.input_shape))]) + else: + pos_emb = self.pos_emb + return pos_emb + +class ConditionalAutoregressive2D(nn.Module): + def __init__(self, input_shape, bins, + width=128, depth=2, heads=1, + attn_dropout=0.0, resid_dropout=0.0, emb_dropout=0.0, mask=True, + zero_out=False, init_scale=1.0, res_scale=False, pos_init=False, + m_attn=0.25, m_mlp=1, + checkpoint_res=0, checkpoint_attn=0, checkpoint_mlp=0, + attn_order=0, blocks=None, spread=None, x_cond=False, y_cond=False, + encoder_dims=0, only_encode=False, merged_decoder=False, prime_len=None): + super().__init__() + self.input_shape = input_shape + self.input_dims = input_dims = np.prod(input_shape) + self.encoder_dims = encoder_dims + self.bins = bins + self.width = width + self.depth = depth + + self.x_emb = nn.Embedding(bins, width) + nn.init.normal_(self.x_emb.weight, std=0.02 * init_scale) + self.x_emb_dropout = nn.Dropout(emb_dropout) + self.y_cond = y_cond + self.x_cond = x_cond + if not y_cond: + self.start_token = nn.Parameter(get_normal(1, width, std=0.01 * init_scale)) + + self.pos_emb = PositionEmbedding(input_shape=input_shape, width=width, init_scale=init_scale, pos_init=pos_init) + self.pos_emb_dropout = nn.Dropout(emb_dropout) + + self.transformer = Transformer(n_in=width, n_ctx=input_dims, n_head=heads, n_depth=depth, + attn_dropout=attn_dropout, resid_dropout=resid_dropout, + afn='quick_gelu', scale=True, mask=mask, + zero_out=zero_out, init_scale=init_scale, res_scale=res_scale, + m_attn=m_attn, m_mlp=m_mlp, + checkpoint_attn=checkpoint_attn, checkpoint_mlp=checkpoint_mlp, checkpoint_res=checkpoint_res, + attn_order=attn_order, blocks=blocks, spread=spread, + encoder_dims=encoder_dims, prime_len=prime_len) + + self.only_encode = only_encode + self.prime_len = prime_len + if merged_decoder: + # Merged piped model uses this setup + self.add_cond_after_transformer = False + self.share_x_emb_x_out = False + else: + self.add_cond_after_transformer = True + self.share_x_emb_x_out = True + + if not only_encode: + self.x_out = nn.Linear(width, bins, bias=False) + if self.share_x_emb_x_out: + self.x_out.weight = self.x_emb.weight + self.loss = t.nn.CrossEntropyLoss() + + def preprocess(self, x): + # Input: x is NHWC and uint8. Converted to NL and long + # Can include stuff like bitpacking, reordering here. + N = x.shape[0] + return x.view(N, -1).long() + + def postprocess(self, x, sample_tokens=None): + # Convert back from NL and long to NHWC + N = x.shape[0] + assert (0 <= x).all() and (x < self.bins).all() + if sample_tokens is None or sample_tokens==self.input_dims: + return x.view(N, *self.input_shape) + else: + return x.view(N, -1) + + def forward(self, x, x_cond=None, y_cond=None, encoder_kv=None, fp16=False, loss_full=False, + encode=False, get_preds=False, get_acts=False, get_sep_loss=False): + # Preprocess. + with t.no_grad(): + x = self.preprocess(x) + + N, D = x.shape + assert isinstance(x, t.cuda.LongTensor) + assert (0 <= x).all() and (x < self.bins).all() + + if self.y_cond: + assert y_cond is not None + assert y_cond.shape == (N, 1, self.width) + else: + assert y_cond is None + + if self.x_cond: + assert x_cond is not None + assert x_cond.shape == (N, D, self.width) or x_cond.shape == (N, 1, self.width), f"{x_cond.shape} != {(N, D, self.width)} nor {(N, 1, self.width)}. Did you pass the correct --sample_length?" + else: + assert x_cond is None + x_cond = t.zeros((N, 1, self.width), device=x.device, dtype=t.float) + + x_t = x # Target + x = self.x_emb(x) # X emb + x = roll(x, 1) # Shift by 1, and fill in start token + if self.y_cond: + x[:,0] = y_cond.view(N, self.width) + else: + x[:,0] = self.start_token + + x = self.x_emb_dropout(x) + self.pos_emb_dropout(self.pos_emb()) + x_cond # Pos emb and dropout + + x = self.transformer(x, encoder_kv=encoder_kv, fp16=fp16) # Transformer + if self.add_cond_after_transformer: # Piped doesnt add x_cond + x = x + x_cond + + acts = x + if self.only_encode: + return x + x = self.x_out(x) # Predictions + + if get_sep_loss: + assert self.prime_len is not None + x_prime = x[:, :self.prime_len].reshape(-1, self.bins) + x_gen = x[:, self.prime_len:].reshape(-1, self.bins) + + prime_loss = F.cross_entropy(x_prime, x_t[:, :self.prime_len].reshape(-1)) / np.log(2.) + gen_loss = F.cross_entropy(x_gen, x_t[:, self.prime_len:].reshape(-1)) / np.log(2.) + + loss = (prime_loss, gen_loss) # Note order! Prime is first + else: + loss = F.cross_entropy(x.view(-1, self.bins), x_t.view(-1)) / np.log(2.) # Loss + + if get_preds: + return loss, x + elif get_acts: + return loss, acts + else: + return loss, None + + def get_emb(self, sample_t, n_samples, x, x_cond, y_cond): + N, D = n_samples, self.input_dims + if sample_t == 0: + # Fill in start token + x = t.empty(n_samples, 1, self.width).cuda() + if self.y_cond: + x[:, 0] = y_cond.view(N, self.width) + else: + x[:, 0] = self.start_token + else: + assert isinstance(x, t.cuda.LongTensor) + assert (0 <= x).all() and (x < self.bins).all() + x = self.x_emb(x) + assert x.shape == (n_samples, 1, self.width) + if x_cond.shape == (N, D, self.width): + cond = x_cond[:, sample_t:sample_t + 1, :] + else: + cond = x_cond + x = x + self.pos_emb()[sample_t:sample_t + 1] + cond # Pos emb, dropout is identity at eval time + assert x.shape == (n_samples, 1, self.width) + return x, cond + + def sample(self, n_samples, x_cond=None, y_cond=None, encoder_kv=None, fp16=False, temp=1.0, top_k=0, top_p=0.0, + get_preds=False, sample_tokens=None): + assert self.training == False + + if sample_tokens is None: sample_tokens=self.input_dims + N, D = n_samples, self.input_dims + if self.y_cond: + assert y_cond is not None + assert y_cond.shape == (N, 1, self.width) + else: + assert y_cond is None + + if self.x_cond: + assert x_cond is not None + assert x_cond.shape == (N, D, self.width) or x_cond.shape == (N, 1, self.width), f"Got {x_cond.shape}, expected ({N}, {D}/{1}, {self.width})" + else: + assert x_cond is None + x_cond = t.zeros((N, 1, self.width), dtype=t.float).cuda() + + with t.no_grad(): + xs, x = [], None + if get_preds: + preds = [] + for sample_t in get_range(range(0, sample_tokens)): + x, cond = self.get_emb(sample_t, n_samples, x, x_cond, y_cond) + self.transformer.check_cache(n_samples, sample_t, fp16) + x = self.transformer(x, encoder_kv=encoder_kv, sample=True, fp16=fp16) # Transformer + if self.add_cond_after_transformer: + x = x + cond + assert x.shape == (n_samples, 1, self.width) + x = self.x_out(x) # Predictions + if get_preds: + preds.append(x.clone()) + # Adjust logits + x = x / temp + x = filter_logits(x, top_k=top_k, top_p=top_p) + x = t.distributions.Categorical(logits=x).sample() # Sample and replace x + assert x.shape == (n_samples, 1) + xs.append(x.clone()) + + del x + self.transformer.del_cache() + + x = t.cat(xs, dim=1) + if get_preds: + preds = t.cat(preds, dim=1) + x = self.postprocess(x, sample_tokens) + if get_preds: + return x, preds + else: + return x + + def primed_sample(self, n_samples, x, x_cond=None, y_cond=None, encoder_kv=None, fp16=False, temp=1.0, top_k=0, + top_p=0.0, get_preds=False, chunk_size=None, sample_tokens=None): + assert self.training == False + + if sample_tokens is None: sample_tokens=self.input_dims + # Preprocess. + with t.no_grad(): + x = self.preprocess(x) + assert isinstance(x, t.cuda.LongTensor) + assert (0 <= x).all() and (x < self.bins).all() + assert x.shape[0] == n_samples + xs = t.split(x, 1, dim=1) + xs = list(xs) + assert len(xs) < sample_tokens + + N, D = n_samples, self.input_dims + if self.y_cond: + assert y_cond is not None + assert y_cond.shape == (N, 1, self.width) + else: + assert y_cond is None + + if self.x_cond: + assert x_cond is not None + assert x_cond.shape == (N, D, self.width) or x_cond.shape == (N, 1, self.width), f"Got {x_cond.shape}, expected ({N}, {D}/{1}, {self.width})" + else: + assert x_cond is None + x_cond = t.zeros((N, 1, self.width), dtype=t.float).cuda() + + with t.no_grad(): + if get_preds: + preds = [] + + # Fill up key/value cache for past context by runing forward pass. + # We do so in chunks instead of doing the whole past in one forward pass to reduce max memory usage. + if chunk_size is None: + chunk_size = len(xs) + #assert len(xs) % chunk_size == 0, f'expected {len(xs)} to be divisible by {chunk_size}' + chunk_sizes = split_chunks(len(xs), chunk_size) + x_primes = [] + start = 0 + x = None + for current_chunk_size in get_range(chunk_sizes): + xs_prime, conds_prime = [], [] + for sample_t in range(start, start + current_chunk_size): + x_prime, cond_prime = self.get_emb(sample_t, n_samples, x, x_cond, y_cond) + x = xs[sample_t] + xs_prime.append(x_prime) + conds_prime.append(cond_prime) + start = start + current_chunk_size + + x_prime, cond_prime = t.cat(xs_prime, dim=1), t.cat(conds_prime, dim=1) + assert x_prime.shape == (n_samples, current_chunk_size, self.width) + assert cond_prime.shape == (n_samples, current_chunk_size, self.width) + del xs_prime + del conds_prime + if not get_preds: + del cond_prime + x_prime = self.transformer(x_prime, encoder_kv=encoder_kv, sample=True, fp16=fp16) + + if get_preds: + if self.add_cond_after_transformer: + x_prime = x_prime + cond_prime + assert x_prime.shape == (n_samples, current_chunk_size, self.width) + del cond_prime + x_primes.append(x_prime) + else: + del x_prime + + if get_preds: + x_prime = t.cat(x_primes, dim=1) + assert x_prime.shape == (n_samples, len(xs), self.width) + x_prime = self.x_out(x_prime) # Predictions + preds.append(x_prime) + + empty_cache() + self.transformer.check_cache(n_samples, len(xs), fp16) + + x = xs[-1] + assert x.shape == (n_samples, 1) + empty_cache() + for sample_t in get_range(range(len(xs), sample_tokens)): + x, cond = self.get_emb(sample_t, n_samples, x, x_cond, y_cond) + self.transformer.check_cache(n_samples, sample_t, fp16) + x = self.transformer(x, encoder_kv=encoder_kv, sample=True, fp16=fp16) # Transformer + if self.add_cond_after_transformer: + x = x + cond + assert x.shape == (n_samples, 1, self.width) + x = self.x_out(x) # Predictions + if get_preds: + preds.append(x) + # Adjust logits + x = x / temp + x = filter_logits(x, top_k=top_k, top_p=top_p) + x = t.distributions.Categorical(logits=x).sample() # Sample and replace x + assert x.shape == (n_samples, 1) + xs.append(x.clone()) + + del x + self.transformer.del_cache() + + x = t.cat(xs, dim=1) + if get_preds: + preds = t.cat(preds, dim=1) + x = self.postprocess(x, sample_tokens) + if get_preds: + return x, preds + else: + return x + + def check_sample(self, chunk_size): + bs, l, d = (4, self.input_dims, self.width) + prime = int(self.input_dims//8*7) + enc_l = self.encoder_dims + with t.no_grad(): + y_cond = t.randn(bs, 1, d).cuda() if self.y_cond else None + x_cond = t.randn(bs, l, d).cuda() if self.x_cond else None + encoder_kv = t.randn(bs, enc_l, d).cuda() + + x, preds_sample = self.sample(bs, x_cond, y_cond, encoder_kv, get_preds=True) + loss, preds_forw = self.forward(x, x_cond, y_cond, encoder_kv, get_preds=True) + max_err = t.max(t.abs(preds_sample - preds_forw)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(preds_sample - preds_forw)[:, i, :]) > 1e-6]}" + + x_prime = x.view(bs, -1)[:,:prime] + # unchunked + x, preds_sample = self.primed_sample(bs, x_prime.clone(), x_cond, y_cond, encoder_kv, get_preds=True) + assert (x.view(bs, -1)[:,:prime] == x_prime).all(), "Priming samples don't match" + loss, preds_forw = self.forward(x, x_cond, y_cond, encoder_kv, get_preds=True) + max_err = t.max(t.abs(preds_sample - preds_forw)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(preds_sample - preds_forw)[:, i, :]) > 1e-6]}" + + # chunked + x, preds_sample = self.primed_sample(bs, x_prime.clone(), x_cond, y_cond, encoder_kv, get_preds=True, chunk_size=chunk_size) + assert (x.view(bs, -1)[:,:prime] == x_prime).all(), "Priming samples don't match" + loss, preds_forw = self.forward(x, x_cond, y_cond, encoder_kv, get_preds=True) + max_err = t.max(t.abs(preds_sample - preds_forw)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(preds_sample - preds_forw)[:, i, :]) > 1e-6]}" + + +def test_prior(input_shape, encoder_dims, blocks, heads, chunk_size): + bins = 512 + width = 32 + depth = 2 + prime_len = encoder_dims + for x_cond in [True, False]: + for y_cond in [True, False]: + for attn_order in [0,2,6,12]: + prior = ConditionalAutoregressive2D(input_shape, bins, + width=width, depth=depth, heads=heads, + attn_order=attn_order, blocks=blocks, + x_cond=x_cond, y_cond=y_cond, + encoder_dims=encoder_dims, prime_len=prime_len).cuda() + prior.training = False + prior.check_sample(chunk_size) + print(f"Checked x_cond: {x_cond}, y_cond: {y_cond}, attn_order: {attn_order}") + # prior.apply(_convert_mlp_traced) + # prior.check_sample() + # print(f"Checked traced x_cond: {x_cond}, y_cond: {y_cond}") + + +if __name__ == '__main__': + from jukebox.utils.dist_utils import setup_dist_from_mpi + setup_dist_from_mpi(port=29600) + test_cases = [ + ((6144,), 384, 64, 2, 23), + ((6144,), 384, 64, 2, 8), + ((8192,), 512, 128, 2, 16), + ] + for test_case in test_cases: + test_prior(*test_case) diff --git a/jukebox/prior/conditioners.py b/jukebox/prior/conditioners.py new file mode 100644 index 0000000000000000000000000000000000000000..782c0b4b4c59d744b92421932f3f6f23b659e837 --- /dev/null +++ b/jukebox/prior/conditioners.py @@ -0,0 +1,157 @@ +import torch as t +import torch.nn as nn + +from jukebox.transformer.ops import LayerNorm +from jukebox.vqvae.encdec import DecoderConvBock +from jukebox.utils.torch_utils import assert_shape + +class Conditioner(nn.Module): + def __init__(self, input_shape, bins, down_t, stride_t, out_width, init_scale, zero_out, res_scale, **block_kwargs): + super().__init__() + self.x_shape = input_shape + + # Embedding + self.width = out_width + self.x_emb = nn.Embedding(bins, out_width) + nn.init.normal_(self.x_emb.weight, std=0.02 * init_scale) + + # Conditioner + self.cond = DecoderConvBock(self.width, self.width, down_t, stride_t, **block_kwargs, zero_out=zero_out, res_scale=res_scale) + self.ln = LayerNorm(self.width) + + def preprocess(self, x): + x = x.permute(0,2,1) # NTC -> NCT + return x + + def postprocess(self, x): + x = x.permute(0,2,1) # NCT -> NTC + return x + + def forward(self, x, x_cond=None): + N = x.shape[0] + assert_shape(x, (N, *self.x_shape)) + if x_cond is not None: + assert_shape(x_cond, (N, *self.x_shape, self.width)) + else: + x_cond = 0.0 + # Embed x + x = x.long() + x = self.x_emb(x) + assert_shape(x, (N, *self.x_shape, self.width)) + x = x + x_cond + + # Run conditioner + x = self.preprocess(x) + x = self.cond(x) + x = self.postprocess(x) + x = self.ln(x) + return x + +def flip(x): + def _flip(x): + return x.permute(0,2,1).contiguous() + if isinstance(x, (list, tuple)): + return [flip(z) for z in x] + return _flip(x) + +class SimpleEmbedding(nn.Module): + def __init__(self, bins, out_width, init_scale): + super().__init__() + self.bins = bins + self.emb = nn.Embedding(bins, out_width) + nn.init.normal_(self.emb.weight, std=0.01 * init_scale) + + def forward(self, y): + assert len(y.shape) == 2, f"Expected shape with 2 dims, got {y.shape}" + assert isinstance(y, t.cuda.LongTensor), f"Expected dtype {t.cuda.LongTensor}, got {y.dtype}" + assert (0 <= y).all() and (y < self.bins).all(), f"Bins {self.bins}, got label {y}" + return self.emb(y) + +class RangeEmbedding(nn.Module): + # Interpolating + # Interpolate so that [pos_start, pos_end] <-> position tensor of length n_ctx + # + # Binning + # For each pos in position tensor, find its bin + # [start,end) mapped to [0,1,...,bins-1] + # [start,end) -> [0,1) -> [0, bins) -> floor -> [0,...,bins-1] + # NOTE: Open ended interval on right, so start <= pos < end, not <= end + def __init__(self, n_time, bins, range, out_width, init_scale, clamp=False): + super().__init__() + self.n_time = n_time + self.bins = bins + self.emb = nn.Embedding(bins, out_width) + nn.init.normal_(self.emb.weight, std=0.01 * init_scale) + self.pos_min, self.pos_max = range + self.clamp = clamp + + def forward(self, pos_start, pos_end=None): + # Check if [pos_start,pos_end] in [pos_min, pos_max) + assert len(pos_start.shape) == 2, f"Expected shape with 2 dims, got {pos_start.shape}" + assert (self.pos_min <= pos_start).all() and (pos_start < self.pos_max).all(), f"Range is [{self.pos_min},{self.pos_max}), got {pos_start}" + pos_start = pos_start.float() + if pos_end is not None: + assert len(pos_end.shape) == 2, f"Expected shape with 2 dims, got {pos_end.shape}" + if self.clamp: + pos_end = pos_end.clamp(self.pos_min, self.pos_max) + assert (self.pos_min <= pos_end).all() and (pos_end <= self.pos_max).all(), f"Range is [{self.pos_min},{self.pos_max}), got {pos_end}" + pos_end = pos_end.float() + # Interpolate so that [pos_start, ..., pos_end] <-> position tensor of length n_ctx + n_time = self.n_time + if n_time != 1: + assert pos_end is not None + interpolation = (t.arange(0, n_time, dtype=t.float, device='cuda').view(1,n_time)/n_time) + position = pos_start + (pos_end - pos_start)*interpolation + else: + position = pos_start + + # Bin each value to bins + normalised_position = (position - self.pos_min) / (self.pos_max - self.pos_min) # [0,1) + bins = (self.bins * normalised_position).floor().long().detach() # [0,1) -> [0,1..,bins) -> [0,1...,bins-1] + return self.emb(bins) + +class LabelConditioner(nn.Module): + def __init__(self, y_bins, t_bins, sr, min_duration, max_duration, n_time, out_width, init_scale, max_bow_genre_size, include_time_signal): + super().__init__() + self.n_time = n_time + self.out_width = out_width + assert len(y_bins) == 2, f"Expecting (genre, artist) bins, got {y_bins}" + bow_genre_bins, artist_bins = y_bins + self.max_bow_genre_size = max_bow_genre_size + self.bow_genre_emb = SimpleEmbedding(bow_genre_bins, out_width, init_scale) + self.artist_emb = SimpleEmbedding(artist_bins, out_width, init_scale) + self.include_time_signal = include_time_signal + if self.include_time_signal: + t_ranges = ((min_duration * sr, max_duration * sr), # Total length + (0.0, max_duration * sr), # Absolute pos + (0.0, 1.0)) # Relative pos + assert len(t_ranges) == 3, f"Expecting (total, absolute, relative) ranges, got {t_ranges}" + total_length_range, absolute_pos_range, relative_pos_range = t_ranges + self.total_length_emb = RangeEmbedding(1, t_bins, total_length_range, out_width, init_scale) + self.absolute_pos_emb = RangeEmbedding(n_time, t_bins, absolute_pos_range, out_width, init_scale) + self.relative_pos_emb = RangeEmbedding(n_time, t_bins, relative_pos_range, out_width, init_scale, clamp=True) + + def forward(self, y): + assert len(y.shape) == 2, f"Expected shape with 2 dims, got {y.shape}" + assert y.shape[-1] == 4 + self.max_bow_genre_size, f"Expected shape (N,{4 + self.max_bow_genre_size}), got {y.shape}" + assert isinstance(y, t.cuda.LongTensor), f"Expected dtype {t.cuda.LongTensor}, got {y.dtype}" + N = y.shape[0] + total_length, offset, length, artist, genre = y[:,0:1], y[:,1:2], y[:,2:3], y[:,3:4], y[:,4:] + + # Start embedding of length 1 + artist_emb = self.artist_emb(artist) + # Empty genre slots are denoted by -1. We mask these out. + mask = (genre >= 0).float().unsqueeze(2) + genre_emb = (self.bow_genre_emb(genre.clamp(0)) * mask).sum(dim=1, keepdim=True) + start_emb = genre_emb + artist_emb + assert_shape(start_emb, (N, 1, self.out_width)) + + # Pos embedding of length n_ctx + if self.include_time_signal: + start, end = offset, offset + length + total_length, start, end = total_length.float(), start.float(), end.float() + pos_emb = self.total_length_emb(total_length) + self.absolute_pos_emb(start, end) + self.relative_pos_emb(start/total_length, end/total_length) + assert_shape(pos_emb, (N, self.n_time, self.out_width)) + else: + pos_emb = None + return start_emb, pos_emb \ No newline at end of file diff --git a/jukebox/prior/prior.py b/jukebox/prior/prior.py new file mode 100644 index 0000000000000000000000000000000000000000..3490d73413dac5cb8dbb92bcd9ac90de88ff9e78 --- /dev/null +++ b/jukebox/prior/prior.py @@ -0,0 +1,354 @@ +import numpy as np +import torch as t +import torch.nn as nn +import jukebox.utils.dist_adapter as dist + +from jukebox.transformer.ops import LayerNorm +from jukebox.prior.autoregressive import ConditionalAutoregressive2D +from jukebox.prior.conditioners import Conditioner, LabelConditioner +from jukebox.data.labels import EmptyLabeller, Labeller + +from jukebox.utils.torch_utils import assert_shape +from jukebox.utils.dist_utils import print_once +from jukebox.vqvae.vqvae import calculate_strides + + +""" +Model the prior on vq codes conditioned on timing, artist, genre, lyrics and codes from levels above. +To condition on the timing, genre and artist, we use the LabelConditioner class +To condition on the codes from the level above, we use the Conditioner class +To condition on lyrics, we allow two types of priors: +- Separate Encoder Decoder: This is the usual encoder-decoder style transformer. The encoder transformer autoregressively +models the lyrics, and we use its last layer to produce keys/values that are attened to by the decoder transformer +- Single Encoder Decoder: This is a simplification where we combine them into a single model. We merge the text vocab +and VQ vocab into a single large vocab, and the lyric tokens and VQ tokens into a single longer sequence of tokens which +we autoregressively model together. +""" +class SimplePrior(nn.Module): + def __init__(self, z_shapes, l_bins, encoder, decoder, level, + downs_t, strides_t, labels, prior_kwargs, x_cond_kwargs, y_cond_kwargs, + prime_kwargs, copy_input, labels_v3=False, + merged_decoder=False, single_enc_dec=False): + super().__init__() + + self.use_tokens = prime_kwargs.pop('use_tokens') + self.n_tokens = prime_kwargs.pop('n_tokens') + self.prime_loss_fraction = prime_kwargs.pop('prime_loss_fraction') + + self.copy_input = copy_input + if self.copy_input: + prime_kwargs['bins'] = l_bins + + self.z_shapes = z_shapes + self.levels = len(self.z_shapes) + + self.z_shape = self.z_shapes[level] + + self.level = level + assert level < self.levels, f"Total levels {self.levels}, got level {level}" + + self.l_bins = l_bins + + # Passing functions instead of the vqvae module to avoid getting params + self.encoder = encoder + self.decoder = decoder + + # X conditioning + self.x_cond = (level != (self.levels - 1)) + self.cond_level = level + 1 + + # Y conditioning + self.y_cond = labels + + self.single_enc_dec = single_enc_dec + # X conditioning + if self.x_cond: + self.conditioner_blocks = nn.ModuleList() + conditioner_block = lambda _level: Conditioner(input_shape=z_shapes[_level], + bins=l_bins, + down_t=downs_t[_level], + stride_t=strides_t[_level], + **x_cond_kwargs) + if dist.get_rank() == 0: print(f"Conditioning on 1 above level(s)") + self.conditioner_blocks.append(conditioner_block(self.cond_level)) + + # Y conditioning + if self.y_cond: + self.n_time = self.z_shape[0] # Assuming STFT=TF order and raw=T1 order, so T is first dim + self.y_emb = LabelConditioner(n_time=self.n_time,include_time_signal=not self.x_cond,**y_cond_kwargs) + + # Lyric conditioning + if single_enc_dec: + # Single encoder-decoder transformer + self.prior_shapes = [(self.n_tokens,), prior_kwargs.pop('input_shape')] + self.prior_bins = [prime_kwargs['bins'], prior_kwargs.pop('bins')] + self.prior_dims = [np.prod(shape) for shape in self.prior_shapes] + self.prior_bins_shift = np.cumsum([0, *self.prior_bins])[:-1] + self.prior_width = prior_kwargs['width'] + print_once(f'Creating cond. autoregress with prior bins {self.prior_bins}, ') + print_once(f'dims {self.prior_dims}, ') + print_once(f'shift {self.prior_bins_shift}') + print_once(f'input shape {sum(self.prior_dims)}') + print_once(f'input bins {sum(self.prior_bins)}') + print_once(f'Self copy is {self.copy_input}') + + self.prime_loss_dims, self.gen_loss_dims = self.prior_dims[0], self.prior_dims[1] + self.total_loss_dims = self.prime_loss_dims + self.gen_loss_dims + self.prior = ConditionalAutoregressive2D(input_shape=(sum(self.prior_dims),), + bins=sum(self.prior_bins), + x_cond=(self.x_cond or self.y_cond), y_cond=True, + prime_len=self.prime_loss_dims, + **prior_kwargs) + + else: + # Separate encoder-decoder transformer + if self.n_tokens != 0 and self.use_tokens: + from jukebox.transformer.ops import Conv1D + prime_input_shape = (self.n_tokens,) + self.prime_loss_dims = np.prod(prime_input_shape) + self.prime_acts_width, self.prime_state_width = prime_kwargs['width'], prior_kwargs['width'] + self.prime_prior = ConditionalAutoregressive2D(input_shape=prime_input_shape, x_cond=False, y_cond=False, + only_encode=True, + **prime_kwargs) + self.prime_state_proj = Conv1D(self.prime_acts_width, self.prime_state_width, init_scale=prime_kwargs['init_scale']) + self.prime_state_ln = LayerNorm(self.prime_state_width) + self.prime_bins = prime_kwargs['bins'] + self.prime_x_out = nn.Linear(self.prime_state_width, self.prime_bins, bias=False) + nn.init.normal_(self.prime_x_out.weight, std=0.02 * prior_kwargs['init_scale']) + else: + self.prime_loss_dims = 0 + self.gen_loss_dims = np.prod(self.z_shape) + self.total_loss_dims = self.prime_loss_dims + self.gen_loss_dims + self.prior = ConditionalAutoregressive2D(x_cond=(self.x_cond or self.y_cond), y_cond=self.y_cond, + encoder_dims = self.prime_loss_dims, merged_decoder=merged_decoder, + **prior_kwargs) + + self.n_ctx = self.gen_loss_dims + self.downsamples = calculate_strides(strides_t, downs_t) + self.cond_downsample = self.downsamples[level+1] if level != self.levels - 1 else None + self.raw_to_tokens = np.prod(self.downsamples[:level+1]) + self.sample_length = self.n_ctx*self.raw_to_tokens + if labels: + self.labels_v3 = labels_v3 + self.labeller = Labeller(self.y_emb.max_bow_genre_size, self.n_tokens, self.sample_length, v3=self.labels_v3) + else: + self.labeller = EmptyLabeller() + + print(f"Level:{level}, Cond downsample:{self.cond_downsample}, Raw to tokens:{self.raw_to_tokens}, Sample length:{self.sample_length}") + + + def get_y(self, labels, start, get_indices=False): + if isinstance(self.labeller, EmptyLabeller): + return None + y = labels['y'].clone() + + # Set sample_length to match this level + y[:, 2] = int(self.sample_length) + + # Set offset + y[:, 1:2] = y[:, 1:2] + int(start * self.raw_to_tokens) + + # Set lyric tokens + indices = self.labeller.set_y_lyric_tokens(y, labels) + if get_indices: + return y, indices + else: + return y + + def get_z_conds(self, zs, start, end): + if self.level != self.levels - 1: + assert start % self.cond_downsample == end % self.cond_downsample == 0 + z_cond = zs[self.level + 1][:,start//self.cond_downsample:end//self.cond_downsample] + assert z_cond.shape[1] == self.n_ctx//self.cond_downsample + z_conds = [z_cond] + else: + z_conds = None + return z_conds + + def prior_preprocess(self, xs, conds): + N = xs[0].shape[0] + for i in range(len(xs)): + x, shape, dims = xs[i], self.prior_shapes[i], self.prior_dims[i] + bins, bins_shift = int(self.prior_bins[i]), int(self.prior_bins_shift[i]) + assert isinstance(x, t.cuda.LongTensor), x + assert (0 <= x).all() and (x < bins).all() + #assert_shape(x, (N, *shape)) + xs[i] = (xs[i] + bins_shift).view(N, -1) + + for i in range(len(conds)): + cond, shape, dims = conds[i], self.prior_shapes[i], self.prior_dims[i] + if cond is not None: + assert_shape(cond, (N, dims, self.prior_width)) + else: + conds[i] = t.zeros((N, dims, self.prior_width), dtype=t.float, device='cuda') + + return t.cat(xs, dim=1), t.cat(conds, dim=1) + + def prior_postprocess(self, z): + N = z.shape[0] + dims = (self.prior_dims[0], z.shape[1] - self.prior_dims[0]) + # xs = list(t.split(z, self.prior_dims, dim=1)) + xs = list(t.split(z, dims, dim=1)) + + for i in range(len(xs)): + # x, shape, dims, bins, bins_shift = xs[i], self.prior_shapes[i], self.prior_dims[i], self.prior_bins[i], self.prior_bins_shift[i] + # assert_shape(x, (N, dims)) + shape = self.prior_shapes[i] + bins, bins_shift = int(self.prior_bins[i]), int(self.prior_bins_shift[i]) + # xs[i] = (xs[i] - bins_shift).view(N, *shape) #view(N, -1, *shape[1:]) + xs[i] = (xs[i] - bins_shift).view(N, -1, *shape[1:]) + xs[i] = t.clamp(xs[i], min=0) # If not masking loss, model may have generated lyric/midi tokens which are now shifted <0 by bin_shift + assert (xs[i] < bins).all(), f'rank: {dist.get_rank()}, bins: {bins}, dims {dims}, shape {shape}, prior_shape {self.prior_shapes}, bins_shift {bins_shift}, xs[i]: {xs[i]}' + + return xs[-1] + + def x_emb(self, z_conds): + z_conds = z_conds[:self.cond_level - self.level] + assert len(z_conds) == len(self.conditioner_blocks) == self.cond_level - self.level, f"Expected {len(z_conds)} == {len(self.conditioner_blocks)} == {self.cond_level} - {self.level}" + x_cond = None + for z_cond, conditioner_block in reversed(list(zip(z_conds, self.conditioner_blocks))): + x_cond = conditioner_block(z_cond, x_cond) + return x_cond + + def encode(self, x, start_level=None, end_level=None, bs_chunks=1): + if start_level == None: + start_level = self.level + if end_level == None: + end_level = self.levels + # Get latents + with t.no_grad(): + zs = self.encoder(x, start_level=start_level, end_level=end_level, bs_chunks=bs_chunks) + return zs + + def decode(self, zs, start_level=None, end_level=None, bs_chunks=1): + if start_level == None: + start_level = self.level + if end_level == None: + end_level = self.levels + + assert len(zs) == end_level - start_level + with t.no_grad(): + x_out = self.decoder(zs, start_level=start_level, end_level=end_level, bs_chunks=bs_chunks) + return x_out + + def get_cond(self, z_conds, y): + if y is not None: + assert y.shape[1] == 4 + self.y_emb.max_bow_genre_size + self.n_tokens, f"Expected {4} + {self.y_emb.max_bow_genre_size} + {self.n_tokens}, got {y.shape[1]}" + n_labels = y.shape[1] - self.n_tokens + y, prime = y[:,:n_labels], y[:,n_labels:] + else: + y, prime = None, None + y_cond, y_pos = self.y_emb(y) if self.y_cond else (None, None) + x_cond = self.x_emb(z_conds) if self.x_cond else y_pos + return x_cond, y_cond, prime + + def sample(self, n_samples, z=None, z_conds=None, y=None, fp16=False, temp=1.0, top_k=0, top_p=0.0, + chunk_size=None, sample_tokens=None): + N = n_samples + if z is not None: assert z.shape[0] == N, f"Expected shape ({N},**), got shape {z.shape}" + if y is not None: assert y.shape[0] == N, f"Expected shape ({N},**), got shape {y.shape}" + if z_conds is not None: + for z_cond in z_conds: + assert z_cond.shape[0] == N, f"Expected shape ({N},**), got shape {z_cond.shape}" + + no_past_context = (z is None or z.shape[1] == 0) + if dist.get_rank() == 0: + name = {True: 'Ancestral', False: 'Primed'}[no_past_context] + print(f"{name} sampling {n_samples} samples with temp={temp}, top_k={top_k}, top_p={top_p}") + + with t.no_grad(): + # Currently x_cond only uses immediately above layer + x_cond, y_cond, prime = self.get_cond(z_conds, y) + if self.single_enc_dec: + # assert chunk_size % self.prime_loss_dims == 0. TODO: Check if needed + if no_past_context: + z, x_cond = self.prior_preprocess([prime], [None, x_cond]) + else: + z, x_cond = self.prior_preprocess([prime, z], [None, x_cond]) + if sample_tokens is not None: + sample_tokens += self.n_tokens + z = self.prior.primed_sample(n_samples, z, x_cond, y_cond, fp16=fp16, temp=temp, + top_k=top_k, top_p=top_p, chunk_size=chunk_size, sample_tokens=sample_tokens) + z = self.prior_postprocess(z) + else: + encoder_kv = self.get_encoder_kv(prime, fp16=fp16, sample=True) + if no_past_context: + z = self.prior.sample(n_samples, x_cond, y_cond, encoder_kv, fp16=fp16, temp=temp, top_k=top_k, + top_p=top_p, sample_tokens=sample_tokens) + else: + z = self.prior.primed_sample(n_samples, z, x_cond, y_cond, encoder_kv, fp16=fp16, temp=temp, + top_k=top_k, top_p=top_p, chunk_size=chunk_size, sample_tokens=sample_tokens) + if sample_tokens is None: + assert_shape(z, (N, *self.z_shape)) + return z + + def get_encoder_kv(self, prime, fp16=False, sample=False): + if self.n_tokens != 0 and self.use_tokens: + if sample: + self.prime_prior.cuda() + N = prime.shape[0] + prime_acts = self.prime_prior(prime, None, None, None, fp16=fp16) + assert_shape(prime_acts, (N, self.prime_loss_dims, self.prime_acts_width)) + assert prime_acts.dtype == t.float, f'Expected t.float, got {prime_acts.dtype}' + encoder_kv = self.prime_state_ln(self.prime_state_proj(prime_acts)) + assert encoder_kv.dtype == t.float, f'Expected t.float, got {encoder_kv.dtype}' + if sample: + self.prime_prior.cpu() + if fp16: + encoder_kv = encoder_kv.half() + else: + encoder_kv = None + return encoder_kv + + def get_prime_loss(self, encoder_kv, prime_t): + if self.use_tokens: + encoder_kv = encoder_kv.float() + encoder_kv = self.prime_x_out(encoder_kv) + prime_loss = nn.functional.cross_entropy(encoder_kv.view(-1, self.prime_bins), prime_t.view(-1)) / np.log(2.) + else: + prime_loss = t.tensor(0.0, device='cuda') + return prime_loss + + def z_forward(self, z, z_conds=[], y=None, fp16=False, get_preds=False, get_attn_weights=False): + """ + Arguments: + get_attn_weights (bool or set): Makes forward prop dump + self-attention softmaxes to self.prior.transformer.ws. Either a + set of layer indices indicating which layers to store, or a + boolean value indicating whether to dump all. + """ + assert isinstance(get_attn_weights, (bool, set)) + if get_attn_weights: + self.prior.transformer.set_record_attn(get_attn_weights) + x_cond, y_cond, prime = self.get_cond(z_conds, y) + if self.copy_input: + prime = z[:,:self.n_tokens] + if self.single_enc_dec: + z, x_cond = self.prior_preprocess([prime, z], [None, x_cond]) + (prime_loss, gen_loss), preds = self.prior(z, x_cond, y_cond, fp16=fp16, get_sep_loss=True, get_preds=get_preds) + else: + encoder_kv = self.get_encoder_kv(prime, fp16=fp16) + prime_loss = self.get_prime_loss(encoder_kv, prime) + gen_loss, preds = self.prior(z, x_cond, y_cond, encoder_kv, fp16=fp16, get_preds=get_preds) + loss = (self.prime_loss_fraction*prime_loss*self.prime_loss_dims/self.total_loss_dims) + \ + (gen_loss*self.gen_loss_dims/self.total_loss_dims) + metrics=dict(bpd=gen_loss.clone().detach(), prime_loss=prime_loss.clone().detach(), + gen_loss=gen_loss.clone().detach()) + if get_preds: + metrics["preds"] = preds.clone().detach() + if get_attn_weights: + ws = self.prior.transformer.ws + self.prior.transformer.set_record_attn(False) + return ws + else: + return loss, metrics + + def forward(self, x, y=None, fp16=False, decode=False, get_preds=False): + bs = x.shape[0] + z, *z_conds = self.encode(x, bs_chunks=bs) + loss, metrics = self.z_forward(z=z, z_conds=z_conds, y=y, fp16=fp16, get_preds=get_preds) + if decode: + x_out = self.decode([z, *z_conds]) + else: + x_out = None + return x_out, loss, metrics diff --git a/jukebox/sample.py b/jukebox/sample.py new file mode 100644 index 0000000000000000000000000000000000000000..c5baee3a364d0fbb35dfe9adddf9841386a3e220 --- /dev/null +++ b/jukebox/sample.py @@ -0,0 +1,279 @@ +import os +import torch as t +import jukebox.utils.dist_adapter as dist + +from jukebox.hparams import Hyperparams +from jukebox.data.labels import EmptyLabeller +from jukebox.utils.torch_utils import empty_cache +from jukebox.utils.audio_utils import save_wav, load_audio +from jukebox.make_models import make_model +from jukebox.align import get_alignment +from jukebox.save_html import save_html +from jukebox.utils.sample_utils import split_batch, get_starts +from jukebox.utils.dist_utils import print_once +import fire + +# Sample a partial window of length= prior.n_ctx: + for start in get_starts(total_length, prior.n_ctx, hop_length): + zs = sample_single_window(zs, labels, sampling_kwargs, level, prior, start, hps) + else: + zs = sample_partial_window(zs, labels, sampling_kwargs, level, prior, total_length, hps) + return zs + +# Sample multiple levels +def _sample(zs, labels, sampling_kwargs, priors, sample_levels, hps): + alignments = None + for level in reversed(sample_levels): + prior = priors[level] + prior.cuda() + empty_cache() + + # Set correct total_length, hop_length, labels and sampling_kwargs for level + assert hps.sample_length % prior.raw_to_tokens == 0, f"Expected sample_length {hps.sample_length} to be multiple of {prior.raw_to_tokens}" + total_length = hps.sample_length//prior.raw_to_tokens + hop_length = int(hps.hop_fraction[level]*prior.n_ctx) + zs = sample_level(zs, labels[level], sampling_kwargs[level], level, prior, total_length, hop_length, hps) + + prior.cpu() + empty_cache() + + # Decode sample + x = prior.decode(zs[level:], start_level=level, bs_chunks=zs[level].shape[0]) + + if dist.get_world_size() > 1: + logdir = f"{hps.name}_rank_{dist.get_rank()}/level_{level}" + else: + logdir = f"{hps.name}/level_{level}" + if not os.path.exists(logdir): + os.makedirs(logdir) + t.save(dict(zs=zs, labels=labels, sampling_kwargs=sampling_kwargs, x=x), f"{logdir}/data.pth.tar") + save_wav(logdir, x, hps.sr) + if alignments is None and priors[-1] is not None and priors[-1].n_tokens > 0 and not isinstance(priors[-1].labeller, EmptyLabeller): + alignments = get_alignment(x, zs, labels[-1], priors[-1], sampling_kwargs[-1]['fp16'], hps) + save_html(logdir, x, zs, labels[-1], alignments, hps) + return zs + +# Generate ancestral samples given a list of artists and genres +def ancestral_sample(labels, sampling_kwargs, priors, hps): + sample_levels = list(range(len(priors))) + zs = [t.zeros(hps.n_samples,0,dtype=t.long, device='cuda') for _ in range(len(priors))] + zs = _sample(zs, labels, sampling_kwargs, priors, sample_levels, hps) + return zs + +# Continue ancestral sampling from previously saved codes +def continue_sample(zs, labels, sampling_kwargs, priors, hps): + sample_levels = list(range(len(priors))) + zs = _sample(zs, labels, sampling_kwargs, priors, sample_levels, hps) + return zs + +# Upsample given already generated upper-level codes +def upsample(zs, labels, sampling_kwargs, priors, hps): + sample_levels = list(range(len(priors) - 1)) + zs = _sample(zs, labels, sampling_kwargs, priors, sample_levels, hps) + return zs + +# Prompt the model with raw audio input (dimension: NTC) and generate continuations +def primed_sample(x, labels, sampling_kwargs, priors, hps): + sample_levels = list(range(len(priors))) + zs = priors[-1].encode(x, start_level=0, end_level=len(priors), bs_chunks=x.shape[0]) + zs = _sample(zs, labels, sampling_kwargs, priors, sample_levels, hps) + return zs + +# Load `duration` seconds of the given audio files to use as prompts +def load_prompts(audio_files, duration, hps): + xs = [] + for audio_file in audio_files: + x = load_audio(audio_file, sr=hps.sr, duration=duration, offset=0.0, mono=True) + x = x.T # CT -> TC + xs.append(x) + while len(xs) < hps.n_samples: + xs.extend(xs) + xs = xs[:hps.n_samples] + x = t.stack([t.from_numpy(x) for x in xs]) + x = x.to('cuda', non_blocking=True) + return x + +# Load codes from previous sampling run +def load_codes(codes_file, duration, priors, hps): + data = t.load(codes_file, map_location='cpu') + zs = [z.cuda() for z in data['zs']] + assert zs[-1].shape[0] == hps.n_samples, f"Expected bs = {hps.n_samples}, got {zs[-1].shape[0]}" + del data + if duration is not None: + # Cut off codes to match duration + top_raw_to_tokens = priors[-1].raw_to_tokens + assert duration % top_raw_to_tokens == 0, f"Cut-off duration {duration} not an exact multiple of top_raw_to_tokens" + assert duration//top_raw_to_tokens <= zs[-1].shape[1], f"Cut-off tokens {duration//priors[-1].raw_to_tokens} longer than tokens {zs[-1].shape[1]} in saved codes" + zs = [z[:,:duration//prior.raw_to_tokens] for z, prior in zip(zs, priors)] + return zs + +# Generate and save samples, alignment, and webpage for visualization. +def save_samples(model, device, hps, sample_hps): + print(hps) + from jukebox.lyricdict import poems, gpt_2_lyrics + vqvae, priors = make_model(model, device, hps) + + assert hps.sample_length//priors[-2].raw_to_tokens >= priors[-2].n_ctx, f"Upsampling needs atleast one ctx in get_z_conds. Please choose a longer sample length" + + total_length = hps.total_sample_length_in_seconds * hps.sr + offset = 0 + + # Set artist/genre/lyrics for your samples here! + # We used different label sets in our models, but you can write the human friendly names here and we'll map them under the hood for each model. + # For the 5b/5b_lyrics model and the upsamplers, labeller will look up artist and genres in v2 set. (after lowercasing, removing non-alphanumerics and collapsing whitespaces to _). + # For the 1b_lyrics top level, labeller will look up artist and genres in v3 set (after lowercasing). + metas = [dict(artist = "Alan Jackson", + genre = "Country", + lyrics = poems['ozymandias'], + total_length=total_length, + offset=offset, + ), + dict(artist="Joe Bonamassa", + genre="Blues Rock", + lyrics=gpt_2_lyrics['hottub'], + total_length=total_length, + offset=offset, + ), + dict(artist="Frank Sinatra", + genre="Classic Pop", + lyrics=gpt_2_lyrics['alone'], + total_length=total_length, + offset=offset, + ), + dict(artist="Ella Fitzgerald", + genre="Jazz", + lyrics=gpt_2_lyrics['count'], + total_length=total_length, + offset=offset, + ), + dict(artist="Céline Dion", + genre="Pop", + lyrics=gpt_2_lyrics['darkness'], + total_length=total_length, + offset=offset, + ), + ] + while len(metas) < hps.n_samples: + metas.extend(metas) + metas = metas[:hps.n_samples] + + labels = [prior.labeller.get_batch_labels(metas, 'cuda') for prior in priors] + for label in labels: + assert label['y'].shape[0] == hps.n_samples + + lower_level_chunk_size = 32 + lower_level_max_batch_size = 16 + if model == '1b_lyrics': + chunk_size = 32 + max_batch_size = 16 + else: + chunk_size = 16 + max_batch_size = 3 + sampling_kwargs = [dict(temp=0.99, fp16=True, chunk_size=lower_level_chunk_size, max_batch_size=lower_level_max_batch_size), + dict(temp=0.99, fp16=True, chunk_size=lower_level_chunk_size, max_batch_size=lower_level_max_batch_size), + dict(temp=0.99, fp16=True, chunk_size=chunk_size, max_batch_size=max_batch_size)] + + if sample_hps.mode == 'ancestral': + ancestral_sample(labels, sampling_kwargs, priors, hps) + elif sample_hps.mode in ['continue', 'upsample']: + assert sample_hps.codes_file is not None + top_raw_to_tokens = priors[-1].raw_to_tokens + if sample_hps.prompt_length_in_seconds is not None: + duration = (int(sample_hps.prompt_length_in_seconds * hps.sr) // top_raw_to_tokens) * top_raw_to_tokens + else: + duration = None + zs = load_codes(sample_hps.codes_file, duration, priors, hps) + if sample_hps.mode == 'continue': + continue_sample(zs, labels, sampling_kwargs, priors, hps) + elif sample_hps.mode == 'upsample': + upsample(zs, labels, sampling_kwargs, priors, hps) + elif sample_hps.mode == 'primed': + assert sample_hps.audio_file is not None + assert sample_hps.prompt_length_in_seconds is not None + audio_files = sample_hps.audio_file.split(',') + top_raw_to_tokens = priors[-1].raw_to_tokens + duration = (int(sample_hps.prompt_length_in_seconds * hps.sr) // top_raw_to_tokens) * top_raw_to_tokens + x = load_prompts(audio_files, duration, hps) + primed_sample(x, labels, sampling_kwargs, priors, hps) + else: + raise ValueError(f'Unknown sample mode {sample_hps.mode}.') + + +def run(model, mode='ancestral', codes_file=None, audio_file=None, prompt_length_in_seconds=None, port=29500, **kwargs): + from jukebox.utils.dist_utils import setup_dist_from_mpi + rank, local_rank, device = setup_dist_from_mpi(port=port) + hps = Hyperparams(**kwargs) + sample_hps = Hyperparams(dict(mode=mode, codes_file=codes_file, audio_file=audio_file, prompt_length_in_seconds=prompt_length_in_seconds)) + + with t.no_grad(): + save_samples(model, device, hps, sample_hps) + +if __name__ == '__main__': + fire.Fire(run) diff --git a/jukebox/save_html.py b/jukebox/save_html.py new file mode 100644 index 0000000000000000000000000000000000000000..fc0fcada6a7f3dd7d550dcca124cdb569eddd1ae --- /dev/null +++ b/jukebox/save_html.py @@ -0,0 +1,130 @@ +import os +import json +import numpy as np +from PIL import Image, ImageFilter +import soundfile + +def save_html(logdir, x, zs, labels, alignments, hps): + level = hps.levels - 1 # Top level used + z = zs[level] + bs, total_length = z.shape[0], z.shape[1] + + with open(f'{logdir}/index.html', 'w') as html: + print(f"{logdir}", + file=html) + print("", file=html) + + for item in range(bs): + data = dict(wav=x[item].cpu().numpy(), sr=hps.sr, + info=labels['info'][item], + total_length=total_length, + total_tokens=len(labels['info'][item]['full_tokens']), + alignment=alignments[item] if alignments is not None else None) + item_dir = f'{logdir}/item_{item}' + _save_item_html(item_dir, item, item, data) + print(f"", file=html) + print("", file=html) + +def _save_item_html(item_dir, item_id, item_name, data): + # replace gs:// with /root/samples/ + + # an html for each sample. Main html has a selector to get us id of this? + if not os.path.exists(item_dir): + os.makedirs(item_dir) + + with open(f'{item_dir}/index.html', 'w') as html: + print(f"{item_name}", + file=html) + print("", file=html) + total_length = data['total_length'] + total_tokens = data['total_tokens'] + alignment = data['alignment'] + lyrics = data["info"]["lyrics"] + wav, sr = data['wav'], data['sr'] + genre, artist = data["info"]["genre"], data["info"]["artist"] + + # Strip unused columns + if alignment is not None: + assert alignment.shape == (total_length, total_tokens) + assert len(lyrics) == total_tokens, f'Total_tokens: {total_tokens}, Lyrics Len: {len(lyrics)}. Lyrics: {lyrics}' + max_attn_at_token = np.max(alignment, axis=0) + assert len(max_attn_at_token) == total_tokens + for token in reversed(range(total_tokens)): + if max_attn_at_token[token] > 0: + break + alignment = alignment[:,:token+1] + lyrics = lyrics[:token+1] + total_tokens = token+1 + + # Small alignment image + im = Image.fromarray(np.uint8(alignment * 255)).resize((512, 1024)).transpose(Image.ROTATE_90) + img_src = f'align.png' + im.save(f'{item_dir}/{img_src}') + print(f"", file=html) + + # Smaller alignment json for animation + total_alignment_length = total_length // 16 + alignment = Image.fromarray(np.uint8(alignment * 255)).resize((total_tokens, total_alignment_length)) + alignment = alignment.filter(ImageFilter.GaussianBlur(radius=1.5)) + alignment = np.asarray(alignment).tolist() + align_src = f'align.json' + with open(f'{item_dir}/{align_src}', 'w') as f: + json.dump(alignment, f) + + # Audio + wav_src = f'audio.wav' + soundfile.write(f'{item_dir}/{wav_src}', wav, samplerate=sr, format='wav') + print(f"", file=html) + + + # Labels and Lyrics + print(f"
", end="", file=html)
+        print(f"
Artist {artist}, Genre {genre}
", file=html) + lyrics = [c for c in lyrics] # already characters actually + lyrics = [''] + lyrics[:-1] # input lyrics are shifted by 1 + for i, c in enumerate(lyrics): + print(f"{c}", end="", file=html) + print(f"
", file=html) + with open(f'{item_dir}/lyrics.json', 'w') as f: + json.dump(lyrics, f) + + if alignment is not None: + # JS for alignment animation + print("""""", file=html) + print("", file=html) diff --git a/jukebox/train.py b/jukebox/train.py new file mode 100644 index 0000000000000000000000000000000000000000..4532232aad0e161e76c06b86a1ae716dab27cc8d --- /dev/null +++ b/jukebox/train.py @@ -0,0 +1,345 @@ +""" +Ability to train vq-vae and prior +First try for random inputs +Then from maestros +""" +import sys +import fire +import warnings +import numpy as np +import torch as t +import jukebox.utils.dist_adapter as dist +from torch.nn.parallel import DistributedDataParallel + +from jukebox.hparams import setup_hparams +from jukebox.make_models import make_vqvae, make_prior, restore_opt, save_checkpoint +from jukebox.utils.logger import init_logging +from jukebox.utils.audio_utils import audio_preprocess, audio_postprocess +from jukebox.utils.torch_utils import zero_grad, count_parameters +from jukebox.utils.dist_utils import print_once, allreduce, allgather +from jukebox.utils.ema import CPUEMA, FusedEMA, EMA +from jukebox.utils.fp16 import FP16FusedAdam, FusedAdam, LossScalar, clipped_grad_scale, backward +from jukebox.data.data_processor import DataProcessor + +def prepare_aud(x, hps): + x = audio_postprocess(x.detach().contiguous(), hps) + return allgather(x) + +def log_aud(logger, tag, x, hps): + logger.add_audios(tag, prepare_aud(x, hps), hps.sr, max_len=hps.max_len, max_log=hps.max_log) + logger.flush() + +def log_labels(logger, labeller, tag, y, hps): + y = y.cpu().numpy() + txt = '' + for item in range(y.shape[0]): + description = labeller.describe_label(y[item]) + artist, genre, lyrics = description['artist'], description['genre'], description['lyrics'] + txt += f'{item} artist:{artist}, genre:{genre}, lyrics:{lyrics}\n' + logger.add_text(tag, txt) + logger.flush() + +def get_ddp(model, hps): + rank = dist.get_rank() + local_rank = rank % 8 + ddp = DistributedDataParallel(model, device_ids=[local_rank], output_device=local_rank, broadcast_buffers=False, bucket_cap_mb=hps.bucket) + return ddp + +def get_ema(model, hps): + mu = hps.mu or (1. - (hps.bs * hps.ngpus/8.)/1000) + ema = None + if hps.ema and hps.train: + if hps.cpu_ema: + if dist.get_rank() == 0: + print("Using CPU EMA") + ema = CPUEMA(model.parameters(), mu=mu, freq=hps.cpu_ema_freq) + elif hps.ema_fused: + ema = FusedEMA(model.parameters(), mu=mu) + else: + ema = EMA(model.parameters(), mu=mu) + return ema + +def get_lr_scheduler(opt, hps): + def lr_lambda(step): + if hps.lr_use_linear_decay: + lr_scale = hps.lr_scale * min(1.0, step / hps.lr_warmup) + decay = max(0.0, 1.0 - max(0.0, step - hps.lr_start_linear_decay) / hps.lr_decay) + if decay == 0.0: + if dist.get_rank() == 0: + print("Reached end of training") + return lr_scale * decay + else: + return hps.lr_scale * (hps.lr_gamma ** (step // hps.lr_decay)) * min(1.0, step / hps.lr_warmup) + + shd = t.optim.lr_scheduler.LambdaLR(opt, lr_lambda) + + return shd + +def get_optimizer(model, hps): + # Optimizer + betas = (hps.beta1, hps.beta2) + if hps.fp16_opt: + opt = FP16FusedAdam(model.parameters(), lr=hps.lr, weight_decay=hps.weight_decay, betas=betas, eps=hps.eps) + else: + opt = FusedAdam(model.parameters(), lr=hps.lr, weight_decay=hps.weight_decay, betas=betas, eps=hps.eps) + + # lr scheduler + shd = get_lr_scheduler(opt, hps) + + restore_path = hps.restore_prior if hps.prior else hps.restore_vqvae + restore_opt(opt, shd, restore_path) + + # fp16 dynamic loss scaler + scalar = None + if hps.fp16: + rank = dist.get_rank() + local_rank = rank % 8 + scalar = LossScalar(hps.fp16_loss_scale, scale_factor=2 ** (1./hps.fp16_scale_window)) + if local_rank == 0: print(scalar.__dict__) + + zero_grad(model) + return opt, shd, scalar + +def log_inputs(orig_model, logger, x_in, y, x_out, hps, tag="train"): + print(f"Logging {tag} inputs/ouputs") + log_aud(logger, f'{tag}_x_in', x_in, hps) + log_aud(logger, f'{tag}_x_out', x_out, hps) + bs = x_in.shape[0] + if hps.prior: + if hps.labels: + log_labels(logger, orig_model.labeller, f'{tag}_y_in', allgather(y.cuda()), hps) + else: + zs_in = orig_model.encode(x_in, start_level=0, bs_chunks=bs) + x_ds = [orig_model.decode(zs_in[level:], start_level=level, bs_chunks=bs) for level in range(0, hps.levels)] + for i in range(len(x_ds)): + log_aud(logger, f'{tag}_x_ds_start_{i}', x_ds[i], hps) + logger.flush() + +def sample_prior(orig_model, ema, logger, x_in, y, hps): + if ema is not None: ema.swap() + orig_model.eval() + + x_in = x_in[:hps.bs_sample] + bs = x_in.shape[0] + zs_in = orig_model.encode(x_in, start_level=0, bs_chunks=bs) + assert len(zs_in) == hps.levels + x_ds = [orig_model.decode(zs_in[level:], start_level=level, bs_chunks=bs) for level in range(0, hps.levels)] + + if not hps.labels: + y = None + elif hps.level == (hps.levels - 1): + # Topmost level labels in order + y = y[:hps.bs_sample] # t.ones((hps.bs_sample, 1), device=y.device, dtype=t.long) * dist.get_rank() + else: + # Other levels keep labels to match x_cond + y = y[:hps.bs_sample] + + # Temp 1.0 + _, *z_conds = orig_model.encode(x_in, bs_chunks=bs) + z = orig_model.sample(hps.bs_sample, z_conds=z_conds, y=y, fp16=False, temp=1.0) + x_sample = orig_model.decode([z, *z_conds], bs_chunks=bs) + + log_aud(logger, 'sample_x_T1', x_sample, hps) + if hps.prior and hps.labels: + log_labels(logger, orig_model.labeller, f'sample_x_T1', allgather(y.cuda()), hps) + + # Recons + for i in range(len(x_ds)): + log_aud(logger, f'x_ds_start_{i}', x_ds[i], hps) + orig_model.train() + if ema is not None: ema.swap() + logger.flush() + +def evaluate(model, orig_model, logger, metrics, data_processor, hps): + model.eval() + orig_model.eval() + if hps.prior: + _print_keys = dict(l="loss", bpd="bpd") + else: + _print_keys = dict(l="loss", rl="recons_loss", sl="spectral_loss") + + with t.no_grad(): + for i, x in logger.get_range(data_processor.test_loader): + if isinstance(x, (tuple, list)): + x, y = x + else: + y = None + + x = x.to('cuda', non_blocking=True) + if y is not None: + y = y.to('cuda', non_blocking=True) + + x_in = x = audio_preprocess(x, hps) + log_input_output = (i==0) + + if hps.prior: + forw_kwargs = dict(y=y, fp16=hps.fp16, decode=log_input_output) + else: + forw_kwargs = dict(loss_fn=hps.loss_fn, hps=hps) + + x_out, loss, _metrics = model(x, **forw_kwargs) + + # Logging + for key, val in _metrics.items(): + _metrics[key] = val.item() + _metrics["loss"] = loss = loss.item() # Make sure to call to free graph + + # Average and log + for key, val in _metrics.items(): + _metrics[key] = metrics.update(f"test_{key}", val, x.shape[0]) + + with t.no_grad(): + if log_input_output: + log_inputs(orig_model, logger, x_in, y, x_out, hps) + + logger.set_postfix(**{print_key:_metrics[key] for print_key, key in _print_keys.items()}) + + for key, val in _metrics.items(): + logger.add_scalar(f"test_{key}", metrics.avg(f"test_{key}")) + + logger.close_range() + return {key: metrics.avg(f"test_{key}") for key in _metrics.keys()} + +def train(model, orig_model, opt, shd, scalar, ema, logger, metrics, data_processor, hps): + model.train() + orig_model.train() + if hps.prior: + _print_keys = dict(l="loss", bpd="bpd", gn="gn", g_l="gen_loss", p_l="prime_loss") + else: + _print_keys = dict(l="loss", sl="spectral_loss", rl="recons_loss", e="entropy", u="usage", uc="used_curr", gn="gn", pn="pn", dk="dk") + + for i, x in logger.get_range(data_processor.train_loader): + if isinstance(x, (tuple, list)): + x, y = x + else: + y = None + + x = x.to('cuda', non_blocking=True) + if y is not None: + y = y.to('cuda', non_blocking=True) + + x_in = x = audio_preprocess(x, hps) + log_input_output = (logger.iters % hps.save_iters == 0) + + if hps.prior: + forw_kwargs = dict(y=y, fp16=hps.fp16, decode=log_input_output) + else: + forw_kwargs = dict(loss_fn=hps.loss_fn, hps=hps) + + # Forward + x_out, loss, _metrics = model(x, **forw_kwargs) + + # Backward + loss, scale, grad_norm, overflow_loss, overflow_grad = backward(loss=loss, params=list(model.parameters()), + scalar=scalar, fp16=hps.fp16, logger=logger) + # Skip step if overflow + grad_norm = allreduce(grad_norm, op=dist.ReduceOp.MAX) + if overflow_loss or overflow_grad or grad_norm > hps.ignore_grad_norm > 0: + zero_grad(orig_model) + continue + + # Step opt. Divide by scale to include clipping and fp16 scaling + logger.step() + opt.step(scale=clipped_grad_scale(grad_norm, hps.clip, scale)) + zero_grad(orig_model) + lr = hps.lr if shd is None else shd.get_lr()[0] + if shd is not None: shd.step() + if ema is not None: ema.step() + next_lr = hps.lr if shd is None else shd.get_lr()[0] + finished_training = (next_lr == 0.0) + + # Logging + for key, val in _metrics.items(): + _metrics[key] = val.item() + _metrics["loss"] = loss = loss.item() * hps.iters_before_update # Make sure to call to free graph + _metrics["gn"] = grad_norm + _metrics["lr"] = lr + _metrics["lg_loss_scale"] = np.log2(scale) + + # Average and log + for key, val in _metrics.items(): + _metrics[key] = metrics.update(key, val, x.shape[0]) + if logger.iters % hps.log_steps == 0: + logger.add_scalar(key, _metrics[key]) + + # Save checkpoint + with t.no_grad(): + if hps.save and (logger.iters % hps.save_iters == 1 or finished_training): + if ema is not None: ema.swap() + orig_model.eval() + name = 'latest' if hps.prior else f'step_{logger.iters}' + if dist.get_rank() % 8 == 0: + save_checkpoint(logger, name, orig_model, opt, dict(step=logger.iters), hps) + orig_model.train() + if ema is not None: ema.swap() + + # Sample + with t.no_grad(): + if (logger.iters % 12000) in list(range(1, 1 + hps.iters_before_update)) or finished_training: + if hps.prior: + sample_prior(orig_model, ema, logger, x_in, y, hps) + + # Input/Output + with t.no_grad(): + if log_input_output: + log_inputs(orig_model, logger, x_in, y, x_out, hps) + + logger.set_postfix(**{print_key:_metrics[key] for print_key, key in _print_keys.items()}) + if finished_training: + dist.barrier() + exit() + logger.close_range() + return {key: metrics.avg(key) for key in _metrics.keys()} + +def run(hps="teeny", port=29500, **kwargs): + from jukebox.utils.dist_utils import setup_dist_from_mpi + rank, local_rank, device = setup_dist_from_mpi(port=port) + hps = setup_hparams(hps, kwargs) + hps.ngpus = dist.get_world_size() + hps.argv = " ".join(sys.argv) + hps.bs_sample = hps.nworkers = hps.bs + + # Setup dataset + data_processor = DataProcessor(hps) + + # Setup models + vqvae = make_vqvae(hps, device) + print_once(f"Parameters VQVAE:{count_parameters(vqvae)}") + if hps.prior: + prior = make_prior(hps, vqvae, device) + print_once(f"Parameters Prior:{count_parameters(prior)}") + model = prior + else: + model = vqvae + + # Setup opt, ema and distributed_model. + opt, shd, scalar = get_optimizer(model, hps) + ema = get_ema(model, hps) + distributed_model = get_ddp(model, hps) + + logger, metrics = init_logging(hps, local_rank, rank) + logger.iters = model.step + + # Run training, eval, sample + for epoch in range(hps.curr_epoch, hps.epochs): + metrics.reset() + data_processor.set_epoch(epoch) + if hps.train: + train_metrics = train(distributed_model, model, opt, shd, scalar, ema, logger, metrics, data_processor, hps) + train_metrics['epoch'] = epoch + if rank == 0: + print('Train',' '.join([f'{key}: {val:0.4f}' for key,val in train_metrics.items()])) + dist.barrier() + + if hps.test: + if ema: ema.swap() + test_metrics = evaluate(distributed_model, model, logger, metrics, data_processor, hps) + test_metrics['epoch'] = epoch + if rank == 0: + print('Ema',' '.join([f'{key}: {val:0.4f}' for key,val in test_metrics.items()])) + dist.barrier() + if ema: ema.swap() + dist.barrier() + +if __name__ == '__main__': + fire.Fire(run) diff --git a/jukebox/transformer/__init__.py b/jukebox/transformer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/transformer/factored_attention.py b/jukebox/transformer/factored_attention.py new file mode 100644 index 0000000000000000000000000000000000000000..5f9b62940fa06fa1c2b36261c440f5d7839ccecf --- /dev/null +++ b/jukebox/transformer/factored_attention.py @@ -0,0 +1,510 @@ +# Factored attention +import math +import numpy as np +import torch as t +import torch.nn as nn +import torch.nn.functional as F +from jukebox.transformer.ops import Conv1D +from jukebox.utils.checkpoint import checkpoint + +def repeat(x, n, dim): + if dim == -1: + dim = len(x.shape) - 1 + return x.view(int(np.prod(x.shape[:dim+1])), 1, int(np.prod(x.shape[dim+1:]))).repeat(1,n,1).view(*x.shape[:dim], n * x.shape[dim], *x.shape[dim+1:]) + +def get_mask(mask, q_l, kv_l, blocks, spread, device, sample, sample_t): + # returns a mask of shape 1 x 1 x q_l x kv_l or None if masking is not needed. + if mask is None or q_l == 1: + return None + offset = sample_t - q_l if sample else max(kv_l - q_l, 0) + if mask == 'autoregressive': + # Masked dense + mask = t.ones(q_l, kv_l, device=device).tril(offset) + elif mask == 'summary': + # Masked summary + mask = t.nn.functional.pad(t.ones(q_l, q_l, device=device).tril().view(q_l, blocks, q_l // blocks)[:,:-1,-kv_l//blocks:],(0,0,1,0),value=1).contiguous().view(q_l, kv_l) + elif mask == 'prime': + mask = t.ones(q_l, kv_l, device=device).tril(offset) + return mask.view(1,1,q_l,kv_l) + +class FactoredAttention(nn.Module): + def __init__(self, n_in, n_ctx, n_state, n_head, + attn_dropout=0.0, resid_dropout=0.0, + scale=True, mask=False, + zero_out=False, init_scale=1.0, + checkpoint_attn=0, + attn_func=0, blocks=None, spread=None, + encoder_dims=None, prime_len=None): + super().__init__() + self.n_in = n_in + self.n_ctx = n_ctx # NOTE: n_ctx could be different within operations. This is complete n_ctx + self.n_state = n_state + assert n_state % n_head == 0 + self.n_head = n_head + self.scale = scale + self.mask = mask + if attn_func == 6: + self.c_attn = Conv1D(n_in, n_state, init_scale=init_scale) + self.c_enc_kv = Conv1D(n_in, n_state * 2, init_scale=init_scale) + else: + self.c_attn = Conv1D(n_in, n_state * 3, init_scale=init_scale) + self.c_proj = Conv1D(n_state, n_in, zero_out, init_scale=init_scale) + self.attn_dropout = nn.Dropout(attn_dropout) if attn_dropout > 0.0 else lambda x: x + self.resid_dropout = nn.Dropout(resid_dropout) if resid_dropout > 0.0 else lambda x: x + + # Sequence of length l is factored as [blocks, l // blocks] + self.attn_func = attn_func + self.qkv, self.attn, self.attn_mask = { + 0: (self.factored_qkv, self.dense_attn, 'autoregressive'), # Attend to all positions + 1: (self.factored_qkv, self.block_attn, 'autoregressive'), # Attend to your block + 2: (self.factored_qkv, self.transpose_block_attn, 'autoregressive'), # Attend to transpose block + 3: (self.factored_qkv, self.prev_block_attn, None), # Attend to previous block + 4: (self.factored_qkv, self.summary_attn, 'summary'), # Attend to last position of each block + 5: (self.factored_qkv, self.summary_spread_attn, 'summary'), + 6: (self.decode_qkv, self.decode_attn, None), + 7: (self.prime_qkv, self.prime_attn, 'prime') + }[attn_func] # Attend to last k position of each block + + self.blocks = blocks + self.spread = spread + if blocks is not None: + assert n_ctx % blocks == 0 + self.block_ctx = n_ctx // blocks + self.checkpoint_attn = checkpoint_attn # 0: None, 1: Attn after heads split, 2: Attn + + self.sample_t = 0 + self.cache = {} + self.encoder_dims = encoder_dims + self.prime_len = prime_len + self.record_attn = False + self.w = None + + def _attn(self, q, k, v, sample): + scale = 1. / math.sqrt(math.sqrt(self.n_state // self.n_head)) + if self.training: + w = t.matmul(q * scale, k * scale) + else: + w = t.matmul(q, k) + w.mul_(scale*scale) + wtype = w.dtype + w = w.float() + if self.mask: + # Generate appropriate mask to mask out all positions before current + # Might take up lot of memory for dense, so can cache it + mask = get_mask(self.attn_mask, q.size(-2), k.size(-1), self.blocks, self.spread, w.device, sample, self.sample_t) + if mask is not None: + #print(mask) + w = w * mask + -1e9 * (1 - mask) + w = F.softmax(w, dim=-1).type(wtype) + else: + w = F.softmax(w, dim=-1).type(wtype) + if self.record_attn: + self.w = w #.float().cpu().numpy() + if self.attn_func == 7: + # only keep music queries and lyrics keys/values + self.w = self.w[:,:,self.prime_len:,:self.prime_len] + w = self.attn_dropout(w) + a = t.matmul(w, v) + return a + + def merge_heads(self, x): + x = x.permute(0, 2, 1, 3).contiguous() + new_x_shape = (*x.size()[:-2], x.size(-2) * x.size(-1)) + return x.view(*new_x_shape) # in Tensorflow implem: fct merge_states + + def split_heads(self, x, k=False): + new_x_shape = (*x.size()[:-1], self.n_head, x.size(-1) // self.n_head) + x = x.view(*new_x_shape) # in Tensorflow implem: fct split_states + if k: + return x.permute(0, 2, 3, 1) + else: + return x.permute(0, 2, 1, 3) + + def dense_attn(self, query, key, value, sample): + query = self.split_heads(query) + key = self.split_heads(key, k=True) + value = self.split_heads(value) + if self.checkpoint_attn == 1 and not sample: + a = checkpoint(lambda q,k,v,s=sample: self._attn(q,k,v,s), (query, key, value), + (), True) + else: + a = self._attn(query,key,value,sample) + a = self.merge_heads(a) + return a + + def block_attn(self, q, k, v, sample): + blocks, block_ctx = self.blocks, self.block_ctx # block_ctx is l // blocks for complete l ie l = n_ctx. Sampling has less l + bs, l, d = v.shape # For sample, q_l = 1, k_l = v_l = sample_t + if sample: + assert l == self._suff_cache_len(), f"{l} != {self._suff_cache_len()}" + return self.dense_attn(q, k, v, sample).view(bs, 1, d) + else: + ql = q.shape[1] + q = q.view(bs * ql // block_ctx, block_ctx, d) + if ql < l: + l = ql + k = k[:, -l:].contiguous() + v = v[:, -l:].contiguous() + k = k.view(bs * l // block_ctx, block_ctx, d) + v = v.view(bs * l // block_ctx, block_ctx, d) + return self.dense_attn(q, k, v, sample).view(bs, l, d) + + def transpose_block_attn(self, q, k, v, sample): + blocks, block_ctx = self.blocks, self.block_ctx # block_ctx is l // blocks for complete l ie l = n_ctx. Sampling has less l + bs, l, d = v.shape # For sample, q_l = 1, k_l = v_l = sample_t + if sample: + block_l = (l - 1) % block_ctx + k = k[:,block_l::block_ctx,:] + v = v[:,block_l::block_ctx,:] + return self.dense_attn(q, k, v, sample).view(bs, 1, d) + else: + ql = q.shape[1] + q = q.view(bs, ql // block_ctx, block_ctx, d).transpose(1,2).contiguous().view(bs * block_ctx, ql // block_ctx, d) + k = k.view(bs, l // block_ctx, block_ctx, d).transpose(1,2).contiguous().view(bs * block_ctx, l // block_ctx, d) + v = v.view(bs, l // block_ctx, block_ctx, d).transpose(1,2).contiguous().view(bs * block_ctx, l // block_ctx, d) + return self.dense_attn(q, k, v, sample).view(bs, block_ctx, ql // block_ctx, d).transpose(1,2).contiguous().view(bs, ql, d) + + def prev_block_attn(self, q, k, v, sample): + blocks, block_ctx = self.blocks, self.block_ctx # block_ctx is l // blocks for complete l ie l = n_ctx. Sampling has less l + bs, l, d = v.shape # For sample, q_l = 1, k_l = v_l = sample_t + if sample: + assert l == self._suff_cache_len(), f"{l} != {self._suff_cache_len()}" + block = (l - 1) // block_ctx + prev_l = (block - 1) * block_ctx + if block > 0: + assert prev_l == 0 + k = k[:, prev_l:prev_l + block_ctx, :] + v = v[:, prev_l:prev_l + block_ctx, :] + else: + k = t.zeros(bs, block_ctx, d, device=q.device, dtype=q.dtype) + v = t.zeros(bs, block_ctx, d, device=q.device, dtype=q.dtype) + return self.dense_attn(q, k, v, sample).view(bs, 1, d) + else: + ql = q.shape[1] + q = q.view(bs * ql // block_ctx, block_ctx, d) + k = t.nn.functional.pad(k.view(bs, l // block_ctx, block_ctx, d)[:, :-1, :, :], (0,0,0,0,1,0)).view(bs * l // block_ctx, block_ctx, d) + v = t.nn.functional.pad(v.view(bs, l // block_ctx, block_ctx, d)[:, :-1, :, :], (0,0,0,0,1,0)).view(bs * l // block_ctx, block_ctx, d) + if ql < l: + qb = ql // block_ctx + kb = l // block_ctx + l = ql + k = k.view(bs, kb, block_ctx, d)[:, -qb:].contiguous().view(bs * qb, block_ctx, d) + v = v.view(bs, kb, block_ctx, d)[:, -qb:].contiguous().view(bs * qb, block_ctx, d) + return self.dense_attn(q, k, v, sample).view(bs, l, d) + + def summary_attn(self, q, k, v, sample): + blocks, block_ctx = self.blocks, self.block_ctx # block_ctx is l // blocks for complete l ie l = n_ctx. Sampling has less l + bs, l, d = v.shape # For sample, q_l = 1, k_l = v_l = sample_t + if sample: + k = t.nn.functional.pad(k[:, block_ctx-1:blocks*block_ctx-1:block_ctx, :],(0,0,1,0)) + v = t.nn.functional.pad(v[:, block_ctx-1:blocks*block_ctx-1:block_ctx, :],(0,0,1,0)) + return self.dense_attn(q, k, v, sample).view(bs, 1, d) + else: + k = t.nn.functional.pad(k.view(bs, blocks, l // blocks, d)[:, :-1, -1, :],(0,0,1,0)) # bs, blocks, d + v = t.nn.functional.pad(v.view(bs, blocks, l // blocks, d)[:, :-1, -1, :],(0,0,1,0)) # bs, blocks, d + return self.dense_attn(q, k, v, sample).view(bs, l, d) + + def summary_spread_attn(self, q, k, v, sample): + blocks, block_ctx, spread = self.blocks, self.block_ctx, self.spread # block_ctx is l // blocks for complete l ie l = n_ctx. Sampling has less l + bs, l, d = v.shape # For sample, q_l = 1, k_l = v_l = sample_t + if sample: + assert False, "Not yet implemented" + # k = t.nn.functional.pad(k,(0,0,block_ctx,(-l)%block_ctx)).view(bs, -1, block_ctx, d)[:,:-1,-spread:,:].contiguous().view(bs, -1, d) + # v = t.nn.functional.pad(v,(0,0,block_ctx,(-l)%block_ctx)).view(bs, -1, block_ctx, d)[:,:-1,-spread:,:].contiguous().view(bs, -1, d) + # return self.dense_attn(q, k, v, sample).view(bs, 1, d) + else: + k = t.nn.functional.pad(k.view(bs, blocks, l // blocks, d)[:, :-1, -spread:, :],(0,0,0,0,1,0)).contiguous().view(bs, blocks * spread, d) # bs, blocks * spread, d + v = t.nn.functional.pad(v.view(bs, blocks, l // blocks, d)[:, :-1, -spread:, :],(0,0,0,0,1,0)).contiguous().view(bs, blocks * spread, d) # bs, blocks * spread, d + return self.dense_attn(q, k, v, sample).view(bs, l, d) + + def prime_attn(self, q, k, v, sample): + prime_len = self._prime_len + k = k[:, :prime_len] + v = v[:, :prime_len] + return self.dense_attn(q, k, v, sample) + + def decode_attn(self, q, k, v, sample): + assert k.shape[1] == v.shape[1] == self.encoder_dims, f'k: {k.shape}, v: {v.shape}, enc_dims: {self.encoder_dims}' + return self.dense_attn(q, k, v, sample) + + def factored_qkv(self, x, encoder_kv=None, sample=False): + curr_ctx = x.shape[1] + assert encoder_kv is None + query, key, value = x.chunk(3, dim=2) + if sample: + self.sample_t += curr_ctx + key, value = self._append_cache(key, value) + l_cache = self._suff_cache_len() + if self._cache_len() > l_cache: + self._slice_cache(-l_cache) + if curr_ctx > 1: + if self.attn_func != 0: + query = self._pad_to_block_ctx(query, query=True) + key = self._pad_to_block_ctx(key) + value = self._pad_to_block_ctx(value) + assert key.shape[1] % self.block_ctx == 0 + assert query.shape[1] % self.block_ctx == 0 + assert key.shape[1] == value.shape[1] + assert query.shape[1] <= key.shape[1] + sample = False + else: + key = self.cache['key'] + value = self.cache['value'] + return query, key, value, sample + + def prime_qkv(self, x, encoder_kv=None, sample=False): + curr_ctx = x.shape[1] + assert encoder_kv is None + query, key, value = x.chunk(3, dim=2) + if sample: + if self._cache_len() < self._prime_len: + self._append_cache(key, value) + if self._cache_len() > self._prime_len: + self._slice_cache(0, self._prime_len) + key, value = self.cache['key'], self.cache['value'] + self.sample_t += curr_ctx + assert key.shape[1] == value.shape[1] == self._suff_cache_len(), f'k: {key.shape}, v: {value.shape}, prime_dims: {self._suff_cache_len()}' + else: + assert key.shape[1] == value.shape[1] == self.n_ctx, f'k: {key.shape}, v: {value.shape}, prime_dims: {self.n_ctx}' + assert key.shape[0] == value.shape[0] == query.shape[0], f'k: {key.shape}, v: {value.shape}, q: {query.shape}' + assert key.shape[2] == value.shape[2] == query.shape[2], f'k: {key.shape}, v: {value.shape}, q: {query.shape}' + return query, key, value, sample + + def decode_qkv(self, x, encoder_kv=None, sample=False): + curr_ctx = x.shape[1] + assert encoder_kv is not None + query = x + if sample: + if self.sample_t == 0: + self.cache['key'], self.cache['value'] = self.c_enc_kv(encoder_kv.type_as(x)).chunk(2, dim=2) + key, value = self.cache['key'], self.cache['value'] + self.sample_t += curr_ctx + else: + key, value = self.c_enc_kv(encoder_kv.type_as(x)).chunk(2, dim=2) + assert key.shape[0] == value.shape[0] == query.shape[0], f'k: {key.shape}, v: {value.shape}, q: {query.shape}' + assert key.shape[1] == value.shape[1] == self.encoder_dims, f'k: {key.shape}, v: {value.shape}, enc_dims: {self.encoder_dims}' + assert key.shape[2] == value.shape[2] == query.shape[2], f'k: {key.shape}, v: {value.shape}, q: {query.shape}' + return query, key, value, sample + + def forward(self, x, encoder_kv=None, sample=False): + curr_ctx = x.shape[1] + x = self.c_attn(x) + query, key, value, sample = self.qkv(x, encoder_kv=encoder_kv, sample=sample) + if self.checkpoint_attn == 2 and not sample: + a = checkpoint(lambda q,k,v,s=sample: self.attn(q,k,v,s), (query, key, value), (), True) + else: + a = self.attn(query,key,value,sample) + if a.shape[1] != curr_ctx: + offset = self._offset(curr_ctx) + a = a[:,offset:offset + curr_ctx,:].contiguous() + a = self.c_proj(a) + return self.resid_dropout(a) + + @property + def _prime_len(self): + prime_len = self.prime_len + assert prime_len is not None + prime_blocks = (prime_len // self.blocks) + 1 + return prime_blocks * self.blocks + + def _offset(self, curr_ctx): + if self.attn_func == 0: + return 0 + return (self.sample_t - curr_ctx) % self.block_ctx + + def _pad_to_block_ctx(self, x, query=False): + l = x.shape[1] + offset = self._offset(l) if query else 0 + n_blocks = (l + offset + self.block_ctx - 1) // self.block_ctx + pad = n_blocks * self.block_ctx - l - offset + if pad == 0 and offset == 0: + return x + else: + return F.pad(x, (0, 0, offset, pad)) + + def _cache_len(self): + return 0 if 'key' not in self.cache else self.cache['key'].shape[1] + + def _suff_cache_len(self): + """ + Precondition: + key and value are appended with the current context and + self.sample_t reflects the 1-indexed sample location in the + context. + """ + if self.attn_func == 0: + return self.sample_t + elif self.attn_func == 1: + return (self.sample_t - 1) % self.block_ctx + 1 + elif self.attn_func == 2: + return self.sample_t + elif self.attn_func == 3: + if self.sample_t <= self.block_ctx: + return self.sample_t + else: + curr_block = (self.sample_t - 1) % self.block_ctx + 1 + prev_block = self.block_ctx + return curr_block + prev_block + elif self.attn_func == 6: + return self.encoder_dims + elif self.attn_func == 7: + return min(self.sample_t, self._prime_len) + else: + raise NotImplementedError() + + def _slice_cache(self, start, end=None): + self.cache['key'] = self.cache['key'][:, start:end] + self.cache['value'] = self.cache['value'][:, start:end] + + def _append_cache(self, key, value): + if 'key' not in self.cache: + self.cache['key'] = key + self.cache['value'] = value + else: + old_key, old_value = key, value + key = t.cat([self.cache['key'], key], dim=1) + value = t.cat([self.cache['value'], value], dim=1) + del self.cache['key'] + del self.cache['value'] + del old_key + del old_value + self.cache['key'] = key + self.cache['value'] = value + return self.cache['key'], self.cache['value'] + + def del_cache(self): + self.sample_t = 0 + if 'key' in self.cache: + del self.cache['key'] + if 'value' in self.cache: + del self.cache['value'] + self.cache = {} + + def check(self): + blocks = self.blocks or 1 + spread = self.spread or 1 + bs, l, d = (4, self.n_ctx, self.n_in) + x = t.randn(bs, l, d).cuda() + x.requires_grad = True + x_out = self.forward(x) # bs, l, d + loss = x_out.mean(dim = -1) # bs, l + pos = 60 + grad = t.autograd.grad(loss[2, pos], x)[0] + + assert grad.shape == (bs, l, d) + assert (grad[:2] == 0).all() + assert (grad[3:] == 0).all() + assert (grad[2, (pos + 1):] == 0).all() + pos_grad = (t.sum(grad[2] ** 2, dim=-1) > 0).nonzero().view(-1).cpu() + + block_pos = pos - (pos % (l // blocks)) + exp_pos_grad = {0: t.arange(pos), + 1: t.arange(block_pos, pos), + 2: t.arange(pos % (l // blocks), pos, l // blocks), + 3: t.arange(block_pos - l // blocks, block_pos), + 4: t.arange(l // blocks - 1, pos, l // blocks), + 5: ((t.arange(pos) % (l // blocks) >= (l // blocks - spread)) & (t.arange(pos) < block_pos)).nonzero().view(-1)}[self.attn_func] + exp_pos_grad = t.cat([exp_pos_grad, t.tensor([pos])], dim=-1) + + assert (len(pos_grad) == len(exp_pos_grad)) and (pos_grad == exp_pos_grad).all(), \ + f"Expected pos grad {exp_pos_grad} got {pos_grad} for attn_func {self.attn_func} pos {pos} l {l} blocks {blocks}" + + def check_cache(self, n_samples, sample_t, fp16): + assert self.sample_t == sample_t, f"{self.sample_t} != {sample_t}" + if sample_t == 0: + assert self.cache == {} + else: + dtype = {True: t.float16, False: t.float32}[fp16] + l_cache = self._suff_cache_len() + assert self.cache['key'].shape == (n_samples, l_cache, self.n_state) + assert self.cache['value'].shape == (n_samples, l_cache, self.n_state) + assert self.cache['key'].dtype == dtype, f"Expected {dtype}, got {self.cache['key'].dtype}" + assert self.cache['value'].dtype == dtype, f"Expected {dtype}, got {self.cache['value'].dtype}" + + def check_sample(self): + t.manual_seed(42) + bs, l, d = (4, self.n_ctx, self.n_in) + prime = 5 + x = t.randn(bs, l, d).cuda() + xs = t.chunk(x, l, dim=1) + assert self.sample_t == 0 + assert self.cache == {} + + with t.no_grad(): + enc_l = self.encoder_dims + encoder_kv = None + if self.attn_func == 6: + encoder_kv = t.randn(bs, enc_l, d).cuda() + + # Normal path + x_out_normal = self.forward(x, encoder_kv=encoder_kv) + + # Sampling path + x_out_sample = t.cat([self.forward(xs[i], encoder_kv=encoder_kv, sample=True) for i in range(l)],dim=1) + max_err = t.max(t.abs(x_out_sample - x_out_normal)) + assert max_err < 1e-8, f"Max sampling err is {max_err} {[i for i in range(l) if t.max(t.abs(x_out_sample - x_out_normal)[:,i,:]) > 1e-8]}" + + with t.no_grad(): + x_out_normal = x_out_normal[:,:prime,:] + # Prime sampling path + self.del_cache() + x_out_sample = self.forward(x[:,:prime,:].contiguous(), encoder_kv=encoder_kv, sample=True) + self.check_cache(bs, prime, False) + + max_err = t.max(t.abs(x_out_sample - x_out_normal)) + assert max_err < 1e-8, f"Max prime sampling err is {max_err} {[i for i in range(prime) if t.max(t.abs(x_out_sample - x_out_normal)[:,i,:]) > 1e-8]}" + + def check_chunks(self, chunk_size): + t.manual_seed(42) + bs, l, d = (4, self.n_ctx, self.n_in) + enc_l = self.encoder_dims + assert l % chunk_size == 0 + n_chunks = l // chunk_size + with t.no_grad(): + encoder_kv = None + x = t.randn(bs, l, d).cuda() + if self.attn_func == 6: + encoder_kv = t.randn(bs, enc_l, d).cuda() + + self.del_cache() + y_forw = self.forward(x, encoder_kv=encoder_kv, sample=False) + self.del_cache() + y_forw_sample = self.forward(x, encoder_kv=encoder_kv, sample=True) + max_err = t.max(t.abs(y_forw - y_forw_sample)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(y_forw - y_forw_sample)[:, i, :]) > 1e-6]}" + + self.del_cache() + x_chunks = t.chunk(x, n_chunks, dim=1) + y_chunks = [] + total_len = 0 + for x_chunk in x_chunks: + y_chunk = self.forward(x_chunk.contiguous(), encoder_kv=encoder_kv, sample=True) + total_len += x_chunk.shape[1] + self.check_cache(bs, total_len, False) + y_chunks.append(y_chunk) + y_forw_in_chunks = t.cat(y_chunks, dim=1) + + max_err = t.max(t.abs(y_forw - y_forw_in_chunks)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(y_forw - y_forw_in_chunks)[:, i, :]) > 1e-6]}" + + +if __name__ == '__main__': + from jukebox.utils.dist_utils import setup_dist_from_mpi + setup_dist_from_mpi(port=29600) + n_in = 16 + n_state = n_in * 2 + n_ctx = 6144 + n_head = 4 + n_depth = 12 + blocks = 64 + chunk_size = 8 + for attn_func in [0, 1, 2, 3, 6, 7]: + encoder_dims = {0: 0, 1: 0, 2: 0, 3: 0, 6: 64, 7: 0}[attn_func] + prime_len = {0: 0, 1: 0, 2: 0, 3: 0, 6: 0, 7: 384}[attn_func] + attn = FactoredAttention(n_in, n_ctx + prime_len, n_state, n_head, mask=True, + attn_func=attn_func, blocks=blocks, + encoder_dims=encoder_dims, prime_len=prime_len) + attn.training = False + attn.check_sample() + attn.check_chunks(chunk_size) + print(f"Checked attn_func: {attn_func}") diff --git a/jukebox/transformer/ops.py b/jukebox/transformer/ops.py new file mode 100644 index 0000000000000000000000000000000000000000..7e12a3bc6711b0f849dd6c795e0df20f2cd2edb0 --- /dev/null +++ b/jukebox/transformer/ops.py @@ -0,0 +1,142 @@ +import math +import numpy as np +import torch as t +import torch.nn as nn +import torch.nn.functional as F + +# Import FusedLayerNorm if we have apex, otherwise use regular LayerNorm +try: + from apex.normalization import FusedLayerNorm + print("Using apex FusedLayerNorm") +except ImportError: + from torch.nn import LayerNorm as FusedLayerNorm + +class LayerNorm(FusedLayerNorm): + def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True): + super().__init__(normalized_shape, eps=eps, elementwise_affine=elementwise_affine) + self.width = np.prod(normalized_shape) + self.max_numel = 65535*self.width + + def forward(self, input): + if input.numel() > self.max_numel: + return F.layer_norm(input.float(), self.normalized_shape, self.weight, self.bias, self.eps).type_as(input) + else: + return super(LayerNorm, self).forward(input.float()).type_as(input) + +def gelu(x): + return 0.5 * x * (1 + t.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * t.pow(x, 3)))) + + +def swish(x): + return x * t.sigmoid(x) + +@t.jit.script +def quick_gelu(x): + return x * t.sigmoid(1.702 * x) + +@t.jit.script +def quick_gelu_bwd(x, grad_output): + sig = t.sigmoid(1.702 * x) + return grad_output * sig * (1.702 * x * (1 - sig) + 1.) + +class QuickGelu(t.autograd.Function): + @staticmethod + def forward(ctx, x): + ctx.save_for_backward(x) + return quick_gelu(x) + + @staticmethod + def backward(ctx, grad_output): + return quick_gelu_bwd(ctx.saved_tensors[0], grad_output) + +def memory_efficient_quick_gelu(x): + return QuickGelu.apply(x) + +ACT_FNS = { + 'relu': t.nn.functional.relu, + 'swish': swish, + 'gelu': gelu, + 'quick_gelu': memory_efficient_quick_gelu #quick_gelu +} + +def _move_to_gpu_and_convert_conv_weights_to_fp16(l): + l.cuda() + if isinstance(l, Conv1D): + l.w.data = l.w.data.half() + +def _convert_conv_weights_to_fp32(l): + if isinstance(l, Conv1D): + l.w.data = l.w.data.float() + +def _convert_conv_weights_to_fp16(l): + if isinstance(l, Conv1D): + l.w.data = l.w.data.half() + +def _convert_embedding_weights_to_fp16(l): + if isinstance(l, t.nn.Embedding): + l.weight.data = l.weight.data.half() + +def _convert_embedding_weights_to_fp32(l): + if isinstance(l, t.nn.Embedding): + l.weight.data = l.weight.data.float() + +class Conv1D(nn.Module): + def __init__(self, n_in, n_out, zero_out=False, init_scale=1.0): + super(Conv1D, self).__init__() + self.n_in = n_in + self.n_out = n_out + if zero_out: + w = t.zeros(n_in, n_out) + else: + w = t.empty(n_in, n_out) + nn.init.normal_(w, std=0.02 * init_scale) + b = t.zeros(n_out) + self.w = nn.Parameter(w) + self.b = nn.Parameter(b) + + def forward(self, x): + size_out = (*x.size()[:-1], self.n_out) + x = t.addmm(self.b.type_as(x), x.view(-1, x.size(-1)), self.w.type_as(x)) # If x if float then float else half + x = x.view(*size_out) + return x + +# For large contexts, mask's can take up memory, so you can make a single saved mask for all layers +class Mask(nn.Module): + def __init__(self, n_ctx): + super().__init__() + self.register_buffer('b', t.tril(t.ones(n_ctx, n_ctx)).view(1, 1, n_ctx, n_ctx)) + + def forward(self, w): + w = w * self.b + -1e9 * (1 - self.b) # For fp16 do w = w.float().masked_fill(self.b, float('-inf') + return w + +def filter_logits(logits, top_k=0, top_p=0.0, filter_value=-float('Inf')): + """ Filter a distribution of logits using top-k and/or nucleus (top-p) filtering + Args: + logits: logits distribution shape (vocabulary size) + top_k >0: keep only top k tokens with highest probability (top-k filtering). + top_p >0.0: keep the top tokens with cumulative probability >= top_p (nucleus filtering). + """ + #assert logits.dim() == 2 # batch size 1 for now - could be updated for more but the code would be less clear + logits = logits.clone() + top_k = min(top_k, logits.size(-1)) # Safety check + assert (top_k == 0) or (top_p == 0.0) + if top_k > 0: + # Remove all tokens with a probability less than the last token of the top-k + indices_to_remove = logits < t.topk(logits, top_k, dim=-1)[0][..., -1:] + logits[indices_to_remove] = filter_value + + if top_p > 0.0: + sorted_logits, sorted_indices = t.sort(logits, descending=True, dim=-1) + cumulative_probs = t.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1) + + # Remove tokens with cumulative probability above the threshold + sorted_indices_to_remove = cumulative_probs > top_p + # Shift the indices to the right to keep also the first token above the threshold + sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone() + sorted_indices_to_remove[..., 0] = 0 + + #indices_to_remove = sorted_indices[sorted_indices_to_remove] + indices_to_remove = t.zeros_like(logits, dtype=t.uint8).scatter_(dim=-1, index=sorted_indices, src=sorted_indices_to_remove) + logits[indices_to_remove] = filter_value + return logits diff --git a/jukebox/transformer/transformer.py b/jukebox/transformer/transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..b78cbb4d141729b3046e10554febea04405436d2 --- /dev/null +++ b/jukebox/transformer/transformer.py @@ -0,0 +1,239 @@ +import functools +import numpy as np +import torch as t +import torch.nn as nn +import jukebox.utils.dist_adapter as dist + +from jukebox.transformer.ops import Conv1D, ACT_FNS, LayerNorm +from jukebox.transformer.factored_attention import FactoredAttention +from jukebox.utils.checkpoint import checkpoint + +def _convert_mlp_traced(l): + if isinstance(l, ResAttnBlock): + l.mlp = t.jit.trace(l.mlp, t.randn(1, 1, l.n_in).cuda()) + +def _convert_mlp_traced_fp16(l): + if isinstance(l, ResAttnBlock): + l.mlp = t.jit.trace(l.mlp, t.randn(1, 1, l.n_in).cuda().half()) + +class MLP(nn.Module): + def __init__(self, n_in, n_state, resid_dropout=0.0, afn='quick_gelu', zero_out=False, init_scale=1.0): + super().__init__() + self.c_fc = Conv1D(n_in, n_state, init_scale=init_scale) + self.c_proj = Conv1D(n_state, n_in, zero_out, init_scale=init_scale) + self.act = ACT_FNS[afn] + self.resid_dropout = nn.Dropout(resid_dropout) if resid_dropout > 0.0 else lambda x: x + + def forward(self, x): + m = self.act(self.c_fc(x)) + m = self.c_proj(m) + return self.resid_dropout(m) + +class ResAttnBlock(nn.Module): + def __init__(self, n_in, n_ctx, n_head, + attn_dropout=0.0, resid_dropout=0.0, + afn='quick_gelu', scale=True, mask=False, + zero_out=False, init_scale=1.0, res_scale=1.0, + m_attn = 0.25, m_mlp = 1., + checkpoint_attn = 0, checkpoint_mlp = 0, + attn_func=0, blocks=None, spread=None, + encoder_dims=None, prime_len=None): + super().__init__() + self.attn = FactoredAttention(n_in=n_in, n_ctx=n_ctx, n_state=int(m_attn * n_in), n_head=n_head, + attn_dropout=attn_dropout, resid_dropout=resid_dropout, + scale=scale, mask=mask, + zero_out=zero_out, init_scale=init_scale, + checkpoint_attn=checkpoint_attn, + attn_func=attn_func, blocks=blocks, spread=spread, + encoder_dims=encoder_dims, prime_len=prime_len) + self.ln_0 = LayerNorm(n_in) + self.mlp = MLP(n_in=n_in, n_state=int(m_mlp * n_in), + resid_dropout=resid_dropout, + afn=afn, + zero_out=zero_out, init_scale=init_scale) + self.ln_1 = LayerNorm(n_in) + self.res_scale = res_scale + + self.checkpoint_attn = checkpoint_attn + self.checkpoint_mlp = checkpoint_mlp + self.n_in = n_in + self.attn_func = attn_func + + def forward(self, x, encoder_kv, sample=False): + if sample: + a = self.attn(self.ln_0(x), encoder_kv, sample) + m = self.mlp(self.ln_1(x + a)) + else: + if self.attn_func == 6: + assert encoder_kv is not None + a = checkpoint(lambda _x,_enc_kv,_s=sample: self.attn(self.ln_0(_x),_enc_kv,_s), + (x,encoder_kv), + (*self.attn.parameters(), *self.ln_0.parameters()), + self.checkpoint_attn == 3) # 2 recomputes after the projections, and 1 recomputes after head splitting. + else: + assert encoder_kv is None + a = checkpoint(lambda _x,_enc_kv=None,_s=sample: self.attn(self.ln_0(_x),_enc_kv,_s), + (x,), + (*self.attn.parameters(), *self.ln_0.parameters()), + self.checkpoint_attn == 3) # 2 recomputes after the projections, and 1 recomputes after head splitting. + m = checkpoint(lambda _x: self.mlp(self.ln_1(_x)), (x + a,), + (*self.mlp.parameters(), *self.ln_1.parameters()), + self.checkpoint_mlp == 1) + if self.res_scale == 1.0: + h = x + a + m + else: + h = x + self.res_scale * (a + m) + return h + +class Transformer(nn.Module): + def __init__(self, n_in, n_ctx, n_head, n_depth, + attn_dropout=0.0, resid_dropout=0.0, + afn='quick_gelu', scale=True, mask=False, + zero_out=False, init_scale=1.0, res_scale=False, + m_attn=0.25, m_mlp=1., + checkpoint_attn=0, checkpoint_mlp=0, checkpoint_res=0, + attn_order=0, blocks=None, spread=None, + encoder_dims=None, prime_len=None): + super().__init__() + self.n_in = n_in + self.n_ctx = n_ctx + self.encoder_dims = encoder_dims + self.blocks = blocks + if blocks is not None: + assert n_ctx % blocks == 0 + self.block_ctx = n_ctx // blocks + self.prime_len = prime_len + self.n_head = n_head + + res_scale = 1.0 / n_depth if res_scale else 1.0 + + # Orders of attn_func + attn_func = {0: lambda d: 0, # Complete dense attn + 1: lambda d: [1,2][d%2], # Alternate row and column attn + 2: lambda d: [1,2,3][d % 3], # Alternate row, column and previous row attn + 3: lambda d: [1,4][d % 2], # Alternate row and last column + 4: lambda d: [1,5][d % 2], # Alternate row and last k columns + 5: lambda d: [1,4,1,1][d % 4], # Alternate row, last column, row, row + 6: lambda d: [1,2,3,6][d % 4], + 7: lambda d: [*[1,2,3]*5,6][d%16], + 8: lambda d: [1,2,3,1,2,3,1,2,3,6][d%10], # Used by separated_enc_dec model with lyrics + 9: lambda d: [1,2,3,0][d % 4], + 10: lambda d: [*[1,2,3,1,2,3,1,2,3],*[1,2,3,1,2,3,1,2,3,6]*7][d%79], # Used by large separated_enc_dec model with lyrics + 11: lambda d: [6,6,0][d%3] if d%16 == 15 else [1,2,3][d%3], + 12: lambda d: [7,7,0][d%3] if d%16 == 15 else [1,2,3][d%3], # Used by single_enc_dec model with lyrics + }[attn_order] + + attn_cycle = {0:1, 1:2, 2:3, 3:2, 4:2, 5:4, 6:4, 7:16, 8:10, 9:4, 10:79, 11:16, 12:16}[attn_order] + #assert n_depth % attn_cycle == 0, f'Depth {n_depth} not a multiple of cycle {attn_cycle} for attn_order {attn_order}' + + attn_block = lambda d: ResAttnBlock(n_in=n_in, n_ctx=n_ctx, n_head=n_head, + attn_dropout=attn_dropout, resid_dropout=resid_dropout, + afn=afn, scale=scale, mask=mask, + zero_out=zero_out if attn_func(d) !=6 else True, + init_scale=init_scale, res_scale=res_scale, + m_attn=m_attn, m_mlp=m_mlp, + checkpoint_attn=checkpoint_attn, checkpoint_mlp=checkpoint_mlp, + attn_func=attn_func(d), blocks=blocks, spread=spread, + encoder_dims=encoder_dims, prime_len=prime_len) + + self.checkpoint_res = checkpoint_res + self._attn_mods = nn.ModuleList() + for d in range(n_depth): + self._attn_mods.append(attn_block(d)) + self.ws = [] + + + def set_record_attn(self, record_attn): + """ + Arguments: + record_attn (bool or set): Makes forward prop dump self-attention + softmaxes to self.ws. Either a set of layer indices indicating + which layers to store, or a boolean value indicating whether to + dump all. + """ + def _should_record_attn(layer_idx): + if isinstance(record_attn, bool): + return record_attn + return layer_idx in record_attn + for i, l in enumerate(self._attn_mods): + l.attn.record_attn = _should_record_attn(i) + if record_attn: + assert self.ws == [] + for l in self._attn_mods: + assert l.attn.w == None + else: + self.ws = [] + for l in self._attn_mods: + l.attn.w = None + + def forward(self, x, encoder_kv=None, sample=False, fp16=False, fp16_out=False): + if fp16: + x = x.half() + + # Blocks + for i,l in enumerate(self._attn_mods): + if self.checkpoint_res == 1 and not sample: + if l.attn_func == 6: + assert encoder_kv is not None + f = functools.partial(l, sample=sample) + x = checkpoint(f, (x, encoder_kv), l.parameters(), True) + else: + f = functools.partial(l, encoder_kv=None, sample=sample) + x = checkpoint(f, (x,), l.parameters(), True) + else: + if l.attn_func == 6: + x = l(x, encoder_kv=encoder_kv, sample=sample) + else: + x = l(x, encoder_kv=None, sample=sample) + if l.attn.record_attn: + self.ws.append(l.attn.w) + if not fp16_out: + x = x.float() + return x + + def check_cache(self, n_samples, sample_t, fp16): + for l in self._attn_mods: + l.attn.check_cache(n_samples, sample_t, fp16) + + def del_cache(self): + for l in self._attn_mods: + l.attn.del_cache() + + def check_sample(self): + bs, l, s, d = (4, self.n_ctx, self.encoder_dims, self.n_in) + prime = 5 + with t.no_grad(): + encoder_kv = t.randn(bs, s, d).cuda() + x = t.randn(bs, l, d).cuda() + y_forw = self.forward(x, encoder_kv=encoder_kv, sample=True) + + self.del_cache() + x_chunks = t.chunk(x, 4, dim=1) + y_chunks = [] + n = 0 + for x_chunk in x_chunks: + self.check_cache(bs, n, False) + y_chunk = self.forward(x_chunk, encoder_kv=encoder_kv, sample=True) + y_chunks.append(y_chunk) + n += x_chunk.shape[1] + self.check_cache(bs, n, False) + y_forw_in_chunks = t.cat(y_chunks, dim=1) + + max_err = t.max(t.abs(y_forw - y_forw_in_chunks)) + assert max_err <= 1e-6, f"Max err is {max_err} {[i for i in range(l) if t.max(t.abs(y_forw - y_forw_in_chunks)[:, i, :]) > 1e-6]}" + + +if __name__ == '__main__': + from jukebox.utils.dist_utils import setup_dist_from_mpi + setup_dist_from_mpi(port=29600) + n_in = 16 + n_ctx = 192 + n_head = 4 + n_depth = 12 + blocks = 16 + for attn_order in [0,2,6]: + encoder_dims = {0: 0, 2: 0, 6: 64}[attn_order] + prior = Transformer(n_in, n_ctx, n_head, n_depth, mask=True, attn_order=attn_order, encoder_dims=encoder_dims, blocks=blocks).cuda() + prior.training = False + prior.check_sample() + print(f"Checked attn_order: {attn_order}") diff --git a/jukebox/utils/__init__.py b/jukebox/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/utils/audio_utils.py b/jukebox/utils/audio_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..dec7b0184ee5b4ce5ac7f6e031c15c7bd9437240 --- /dev/null +++ b/jukebox/utils/audio_utils.py @@ -0,0 +1,148 @@ +import numpy as np +import torch as t +import jukebox.utils.dist_adapter as dist +import soundfile +import librosa +from jukebox.utils.dist_utils import print_once + +class DefaultSTFTValues: + def __init__(self, hps): + self.sr = hps.sr + self.n_fft = 2048 + self.hop_length = 256 + self.window_size = 6 * self.hop_length + +class STFTValues: + def __init__(self, hps, n_fft, hop_length, window_size): + self.sr = hps.sr + self.n_fft = n_fft + self.hop_length = hop_length + self.window_size = window_size + +def calculate_bandwidth(dataset, hps, duration=600): + hps = DefaultSTFTValues(hps) + n_samples = int(dataset.sr * duration) + l1, total, total_sq, n_seen, idx = 0.0, 0.0, 0.0, 0.0, dist.get_rank() + spec_norm_total, spec_nelem = 0.0, 0.0 + while n_seen < n_samples: + x = dataset[idx] + if isinstance(x, (tuple, list)): + x, y = x + samples = x.astype(np.float64) + stft = librosa.core.stft(np.mean(samples, axis=1), hps.n_fft, hop_length=hps.hop_length, win_length=hps.window_size) + spec = np.absolute(stft) + spec_norm_total += np.linalg.norm(spec) + spec_nelem += 1 + n_seen += int(np.prod(samples.shape)) + l1 += np.sum(np.abs(samples)) + total += np.sum(samples) + total_sq += np.sum(samples ** 2) + idx += max(16, dist.get_world_size()) + + if dist.is_available(): + from jukebox.utils.dist_utils import allreduce + n_seen = allreduce(n_seen) + total = allreduce(total) + total_sq = allreduce(total_sq) + l1 = allreduce(l1) + spec_nelem = allreduce(spec_nelem) + spec_norm_total = allreduce(spec_norm_total) + + mean = total / n_seen + bandwidth = dict(l2 = total_sq / n_seen - mean ** 2, + l1 = l1 / n_seen, + spec = spec_norm_total / spec_nelem) + print_once(bandwidth) + return bandwidth + +def audio_preprocess(x, hps): + # Extra layer in case we want to experiment with different preprocessing + # For two channel, blend randomly into mono (standard is .5 left, .5 right) + + # x: NTC + x = x.float() + if x.shape[-1]==2: + if hps.aug_blend: + mix=t.rand((x.shape[0],1), device=x.device) #np.random.rand() + else: + mix = 0.5 + x=(mix*x[:,:,0]+(1-mix)*x[:,:,1]) + elif x.shape[-1]==1: + x=x[:,:,0] + else: + assert False, f'Expected channels {hps.channels}. Got unknown {x.shape[-1]} channels' + + # x: NT -> NTC + x = x.unsqueeze(2) + return x + +def audio_postprocess(x, hps): + return x + +def stft(sig, hps): + return t.stft(sig, hps.n_fft, hps.hop_length, win_length=hps.window_size, window=t.hann_window(hps.window_size, device=sig.device)) + +def spec(x, hps): + return t.norm(stft(x, hps), p=2, dim=-1) + +def norm(x): + return (x.view(x.shape[0], -1) ** 2).sum(dim=-1).sqrt() + +def squeeze(x): + if len(x.shape) == 3: + assert x.shape[-1] in [1,2] + x = t.mean(x, -1) + if len(x.shape) != 2: + raise ValueError(f'Unknown input shape {x.shape}') + return x + +def spectral_loss(x_in, x_out, hps): + hps = DefaultSTFTValues(hps) + spec_in = spec(squeeze(x_in.float()), hps) + spec_out = spec(squeeze(x_out.float()), hps) + return norm(spec_in - spec_out) + +def multispectral_loss(x_in, x_out, hps): + losses = [] + assert len(hps.multispec_loss_n_fft) == len(hps.multispec_loss_hop_length) == len(hps.multispec_loss_window_size) + args = [hps.multispec_loss_n_fft, + hps.multispec_loss_hop_length, + hps.multispec_loss_window_size] + for n_fft, hop_length, window_size in zip(*args): + hps = STFTValues(hps, n_fft, hop_length, window_size) + spec_in = spec(squeeze(x_in.float()), hps) + spec_out = spec(squeeze(x_out.float()), hps) + losses.append(norm(spec_in - spec_out)) + return sum(losses) / len(losses) + +def spectral_convergence(x_in, x_out, hps, epsilon=2e-3): + hps = DefaultSTFTValues(hps) + spec_in = spec(squeeze(x_in.float()), hps) + spec_out = spec(squeeze(x_out.float()), hps) + + gt_norm = norm(spec_in) + residual_norm = norm(spec_in - spec_out) + mask = (gt_norm > epsilon).float() + return (residual_norm * mask) / t.clamp(gt_norm, min=epsilon) + +def log_magnitude_loss(x_in, x_out, hps, epsilon=1e-4): + hps = DefaultSTFTValues(hps) + spec_in = t.log(spec(squeeze(x_in.float()), hps) + epsilon) + spec_out = t.log(spec(squeeze(x_out.float()), hps) + epsilon) + return t.mean(t.abs(spec_in - spec_out)) + +def load_audio(file, sr, offset, duration, mono=False): + # Librosa loads more filetypes than soundfile + x, _ = librosa.load(file, sr=sr, mono=mono, offset=offset/sr, duration=duration/sr) + if len(x.shape) == 1: + x = x.reshape((1, -1)) + return x + + +def save_wav(fname, aud, sr): + # clip before saving? + aud = t.clamp(aud, -1, 1).cpu().numpy() + for i in list(range(aud.shape[0])): + soundfile.write(f'{fname}/item_{i}.wav', aud[i], samplerate=sr, format='wav') + + diff --git a/jukebox/utils/checkpoint.py b/jukebox/utils/checkpoint.py new file mode 100644 index 0000000000000000000000000000000000000000..cfbcccb34d415a50f6bc7ef86334215d54779c18 --- /dev/null +++ b/jukebox/utils/checkpoint.py @@ -0,0 +1,32 @@ +# Simple gradient checkpointing. Works with distributed data parallel +import torch as t + +def checkpoint(func, inputs, params, flag): + if flag: + args = inputs + tuple(params) + return CheckpointFunction.apply(func, len(inputs), *args) + else: + return func(*inputs) + +class CheckpointFunction(t.autograd.Function): + @staticmethod + def forward(ctx, run_function, length, *args): + ctx.run_function = run_function + ctx.input_tensors = list(args[:length]) + ctx.input_params = list(args[length:]) + with t.no_grad(): + output_tensors = ctx.run_function(*ctx.input_tensors) + return output_tensors + + @staticmethod + def backward(ctx, *output_grads): + for i in range(len(ctx.input_tensors)): + temp = ctx.input_tensors[i] + ctx.input_tensors[i] = temp.detach() + ctx.input_tensors[i].requires_grad = temp.requires_grad + with t.enable_grad(): + output_tensors = ctx.run_function(*ctx.input_tensors) + input_grads = t.autograd.grad(output_tensors, ctx.input_tensors + ctx.input_params, output_grads, allow_unused=True) + del ctx.input_tensors + del output_tensors + return (None, None) + input_grads diff --git a/jukebox/utils/dist_adapter.py b/jukebox/utils/dist_adapter.py new file mode 100644 index 0000000000000000000000000000000000000000..b67af947b3ac4f7e37e843b37d0499fc1ea5e7ef --- /dev/null +++ b/jukebox/utils/dist_adapter.py @@ -0,0 +1,86 @@ +import torch.distributed as dist +from enum import Enum + +class ReduceOp(Enum): + SUM = 0, + PRODUCT = 1, + MIN = 2, + MAX = 3 + + def ToDistOp(self): + return { + self.SUM: dist.ReduceOp.SUM, + self.PRODUCT: dist.ReduceOp.PRODUCT, + self.MIN: dist.ReduceOp.MIN, + self.MAX: dist.ReduceOp.MAX + }[self] + +def is_available(): + return dist.is_available() + +def get_rank(): + if is_available(): + return _get_rank() + else: + return 0 + +def get_world_size(): + if is_available(): + return _get_world_size() + else: + return 1 + +def barrier(): + if is_available(): + return _barrier() + #else: do nothing + +def all_gather(tensor_list, tensor): + if is_available(): + return _all_gather(tensor_list, tensor) + else: + tensor_list[0] = tensor + +def all_reduce(tensor, op=ReduceOp.SUM): + if is_available(): + return _all_reduce(tensor, op) + #else: do nothing + +def reduce(tensor, dst, op=ReduceOp.SUM): + if is_available(): + return _reduce(tensor, dst, op) + #else: do nothing + +def broadcast(tensor, src): + if is_available(): + return _broadcast(tensor, src) + #else: do nothing + +def init_process_group(backend, init_method): + if is_available(): + return _init_process_group(backend, init_method) + #else: do nothing + +def _get_rank(): + return dist.get_rank() + +def _barrier(): + return dist.barrier() + +def _get_world_size(): + return dist.get_world_size() + +def _all_gather(tensor_list, tensor): + return dist.all_gather(tensor_list, tensor) + +def _all_reduce(tensor, op): + return dist.all_reduce(tensor, op.ToDistOp()) + +def _reduce(tensor, dst, op): + return dist.reduce(tensor, dst, op.ToDistOp()) + +def _broadcast(tensor, src): + return dist.broadcast(tensor, src) + +def _init_process_group(backend, init_method): + return dist.init_process_group(backend, init_method) \ No newline at end of file diff --git a/jukebox/utils/dist_utils.py b/jukebox/utils/dist_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..ec67fa1db02ecb08fa1bf33d550979d509e9ad14 --- /dev/null +++ b/jukebox/utils/dist_utils.py @@ -0,0 +1,101 @@ +import os +from time import sleep +import torch +import jukebox.utils.dist_adapter as dist + +def print_once(msg): + if (not dist.is_available()) or dist.get_rank()==0: + print(msg) + +def print_all(msg): + if (not dist.is_available()): + print(msg) + elif dist.get_rank()%8==0: + print(f'{dist.get_rank()//8}: {msg}') + +def allgather(x): + xs = [torch.empty_like(x) for _ in range(dist.get_world_size())] + dist.all_gather(xs, x) + xs = torch.cat(xs, dim=0) + return xs + +def allreduce(x, op=dist.ReduceOp.SUM): + x = torch.tensor(x).float().cuda() + dist.all_reduce(x, op=op) + return x.item() + +def allgather_lists(xs): + bs = len(xs) + total_bs = dist.get_world_size()*len(xs) + lengths = torch.tensor([len(x) for x in xs], dtype=t.long, device='cuda') + lengths = allgather(lengths) + assert lengths.shape == (total_bs,) + max_length = torch.max(lengths).item() + + xs = torch.tensor([[*x, *[0]*(max_length - len(x))] for x in xs], device='cuda') + assert xs.shape == (bs, max_length), f'Expected {(bs, max_length)}, got {xs.shape}' + xs = allgather(xs) + assert xs.shape == (total_bs,max_length), f'Expected {(total_bs, max_length)}, got {xs.shape}' + + return [xs[i][:lengths[i]].cpu().numpy().tolist() for i in range(total_bs)] + +def setup_dist_from_mpi( + master_addr="127.0.0.1", backend="nccl", port=29500, n_attempts=5, verbose=False +): + if dist.is_available(): + return _setup_dist_from_mpi(master_addr, backend, port, n_attempts, verbose) + else: + use_cuda = torch.cuda.is_available() + print(f'Using cuda {use_cuda}') + + mpi_rank = 0 + local_rank = 0 + + device = torch.device("cuda", local_rank) if use_cuda else torch.device("cpu") + torch.cuda.set_device(local_rank) + + return mpi_rank, local_rank, device + +def _setup_dist_from_mpi(master_addr, backend, port, n_attempts, verbose): + from mpi4py import MPI # This must be imported in order to get e rrors from all ranks to show up + + mpi_rank = MPI.COMM_WORLD.Get_rank() + mpi_size = MPI.COMM_WORLD.Get_size() + + + os.environ["RANK"] = str(mpi_rank) + os.environ["WORLD_SIZE"] = str(mpi_size) + os.environ["MASTER_ADDR"] = master_addr + os.environ["MASTER_PORT"] = str(port) + os.environ["NCCL_LL_THRESHOLD"] = "0" + os.environ["NCCL_NSOCKS_PERTHREAD"] = "2" + os.environ["NCCL_SOCKET_NTHREADS"] = "8" + + # Pin this rank to a specific GPU on the node + local_rank = mpi_rank % 8 + if torch.cuda.is_available(): + torch.cuda.set_device(local_rank) + + if verbose: + print(f"Connecting to master_addr: {master_addr}") + + # There is a race condition when initializing NCCL with a large number of ranks (e.g 500 ranks) + # We guard against the failure and then retry + for attempt_idx in range(n_attempts): + try: + dist.init_process_group(backend=backend, init_method=f"env://") + assert dist.get_rank() == mpi_rank + + use_cuda = torch.cuda.is_available() + print(f'Using cuda {use_cuda}') + local_rank = mpi_rank % 8 + device = torch.device("cuda", local_rank) if use_cuda else torch.device("cpu") + torch.cuda.set_device(local_rank) + + return mpi_rank, local_rank, device + except RuntimeError as e: + print(f"Caught error during NCCL init (attempt {attempt_idx} of {n_attempts}): {e}") + sleep(1 + (0.01 * mpi_rank)) # Sleep to avoid thundering herd + pass + + raise RuntimeError("Failed to initialize NCCL") diff --git a/jukebox/utils/ema.py b/jukebox/utils/ema.py new file mode 100644 index 0000000000000000000000000000000000000000..94f3b47bfa6dfba9e0a932a1a3beeb54a0575a58 --- /dev/null +++ b/jukebox/utils/ema.py @@ -0,0 +1,94 @@ +import torch +from torch._utils import _flatten_dense_tensors +import numpy as np + +# EMA always in float, as accumulation needs lots of bits +class EMA: + def __init__(self, params, mu=0.999): + self.mu = mu + self.state = [(p, self.get_model_state(p)) for p in params if p.requires_grad] + + def get_model_state(self, p): + return p.data.float().detach().clone() + + def step(self): + for p, state in self.state: + state.mul_(self.mu).add_(1 - self.mu, p.data.float()) + + def swap(self): + # swap ema and model params + for p, state in self.state: + other_state = self.get_model_state(p) + p.data.copy_(state.type_as(p.data)) + state.copy_(other_state) + + +class CPUEMA: + def __init__(self, params, mu=0.999, freq=1): + self.mu = mu**freq + self.state = [(p, self.get_model_state(p)) for p in params if p.requires_grad] + self.freq = freq + self.steps = 0 + + def get_model_state(self, p): + with torch.no_grad(): + state = p.data.float().detach().cpu().numpy() + return state + + def step(self): + with torch.no_grad(): + self.steps += 1 + if self.steps % self.freq == 0: + for i in range(len(self.state)): + p, state = self.state[i] + state = torch.from_numpy(state).cuda() + state.mul_(self.mu).add_(1 - self.mu, p.data.float()) + self.state[i] = (p, state.cpu().numpy()) + + def swap(self): + with torch.no_grad(): + # swap ema and model params + for p, state in self.state: + other_state = self.get_model_state(p) + p.data.copy_(torch.from_numpy(state).type_as(p.data)) + np.copyto(state, other_state) + +class FusedEMA: + def __init__(self, params, mu=0.999): + self.mu = mu + params = list(params) + self.params = {} + self.params['fp16'] = [p for p in params if p.requires_grad and p.data.dtype == torch.float16] + self.params['fp32'] = [p for p in params if p.requires_grad and p.data.dtype != torch.float16] + self.groups = [group for group in self.params.keys() if len(self.params[group]) > 0] + self.state = {} + for group in self.groups: + self.state[group] = self.get_model_state(group) + + def get_model_state(self, group): + params = self.params[group] + return _flatten_dense_tensors([p.data.float() for p in params]) + # if self.fp16: + # return _flatten_dense_tensors([p.data.half() for p in self.param_group if p.dtype]) + # else: + # return _flatten_dense_tensors([p.data for p in self.param_group]) + + def step(self): + for group in self.groups: + self.state[group].mul_(self.mu).add_(1 - self.mu, self.get_model_state(group)) + + def swap(self): + # swap ema and model params + for group in self.groups: + other_state = self.get_model_state(group) + state = self.state[group] + params = self.params[group] + offset = 0 + for p in params: + numel = p.data.numel() + p.data = state.narrow(0, offset, numel).view_as(p.data).type_as(p.data) + offset += numel + + self.state[group] = other_state + + diff --git a/jukebox/utils/fp16.py b/jukebox/utils/fp16.py new file mode 100644 index 0000000000000000000000000000000000000000..eb31c4ee5728d8fc5f72b9aed0d1f89735cea48e --- /dev/null +++ b/jukebox/utils/fp16.py @@ -0,0 +1,303 @@ +# Utils for fp16 training. +import importlib +import math +import numpy as np +import torch +import jukebox.utils.dist_adapter as dist +from torch.optim import Optimizer +from torch._utils import _flatten_dense_tensors + +from jukebox.utils.dist_utils import allreduce + +def adam_step(p: torch.Tensor, out_p: torch.Tensor, exp_avg: torch.Tensor, exp_avg_sq: torch.Tensor, grad: torch.Tensor, + lr: float, beta1: float, beta2: float, eps: float, scale: float, step: int, eps_mode: int, bias_correction: int, weight_decay: float): + assert bias_correction == 1 + assert eps_mode == 1 + + grad = grad.float() + grad.div_(scale) + + # Decay the first and second moment running average coefficient + exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1) + exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1 - beta2) + denom = exp_avg_sq.sqrt().add_(eps) + + bias_correction1 = 1 - beta1 ** step + bias_correction2 = 1 - beta2 ** step + step_size = lr * math.sqrt(bias_correction2) / bias_correction1 + + p.add_(exp_avg/denom + weight_decay*p.float(), alpha=-step_size) + +# Import fused_adam if we have apex, otherwise use regular adam +try: + fused_adam_cuda = importlib.import_module("fused_adam_cuda") + fused_adam_step = fused_adam_cuda.adam + print("Using apex fused_adam_cuda") +except ModuleNotFoundError: + fused_adam_step = adam_step + +def backward(loss, params, scalar, fp16, logger): + # Perform backward + if not fp16: + scale = 1.0 + loss.backward() + gn = grad_norm(params, scale) + return loss, scale, gn, False, False + else: + scale = scalar.get_scale() + loss = (loss.float())*scale + overflow_loss = check_overflow(loss.item()) + overflow_loss = allreduce(int(overflow_loss), op=dist.ReduceOp.MAX) > 0 + if not overflow_loss: + loss.backward() + gn = grad_norm(params, scale) + overflow_grad = check_overflow(gn) + overflow_grad = allreduce(int(overflow_grad), op=dist.ReduceOp.MAX) > 0 + scalar.update_scale(overflow_grad) + else: + gn = 0.0 + overflow_grad = True + loss = (loss.detach().float()) / scale # Should delete computation graph for overflow + if logger.rank == 0: + if loss > 12.: print(f"\nWarning. Loss is {loss}") + if overflow_loss: print(f"\nOverflow in forward. Loss {loss}, lgscale {np.log2(scale)}. Skipping batch completely (no backward, scale update)") + elif overflow_grad: print(f"\nOverflow in backward. Loss {loss}, grad norm {gn}, lgscale {np.log2(scale)}, new lgscale {np.log2(scalar.get_scale())}") + return loss, scale, gn, overflow_loss, overflow_grad + +# Automatic loss scaling +class LossScalar(object): + def __init__(self, + loss_scale, + init_scale=2. ** 16, + scale_factor=2. ** (1. / 1000), + scale_window=1): + if loss_scale == None: + # Use dynamic loss scaling + self.dynamic = True + self.loss_scale = init_scale + else: + self.dynamic = False + self.loss_scale = loss_scale + self.max_loss_scale = 2.**24 + self.scale_factor = scale_factor + self.scale_window = scale_window + self.unskipped = 0 + self.overflow = False + + def get_scale(self): + return self.loss_scale + + def update_scale(self, overflow): + if overflow and self.dynamic: + self.loss_scale /= 2. + self.unskipped = 0 + else: + self.unskipped += 1 + + if self.unskipped == self.scale_window and self.dynamic: + self.loss_scale = min(self.max_loss_scale, self.loss_scale * self.scale_factor) + self.unskipped = 0 + +def check_overflow(val): + return (val == float('inf')) or (val == -float('inf')) or (val != val) + +def grad_norm(params, scale, flat=False): + params = list(params) + if flat: + # Faster but more memory + fp16_grads = [p.grad for p in params if p.grad is not None and p.data.dtype == torch.float16] + fp16_norm = 0.0 if len(fp16_grads) == 0 else float(_flatten_dense_tensors(fp16_grads).norm(p=2, dtype=torch.float32)) + fp32_grads = [p.grad for p in params if p.grad is not None and p.data.dtype != torch.float16] + fp32_norm = 0.0 if len(fp32_grads) == 0 else float(_flatten_dense_tensors(fp32_grads).norm(p=2)) + grad_norm = (fp16_norm**2 + fp32_norm**2)**0.5 + else: + # Slightly slower but less memory + grad_norm = 0.0 + for p in params: + if p.grad is not None: + grad_norm += p.grad.norm(p=2, dtype=torch.float32)**2 + grad_norm = float(grad_norm**0.5) + return grad_norm / scale + +def clipped_grad_scale(grad_norm, max_grad_norm, scale): + clip = grad_norm / max_grad_norm + if clip > 1: + scale = clip * scale + return scale + +class FP16FusedAdam(Optimizer): + def __init__( + self, + params, + lr=1e-3, + bias_correction=True, + betas=(0.9, 0.999), + eps=1e-8, + eps_inside_sqrt=False, + weight_decay=0.0, + amsgrad=False, + ): + if amsgrad: + raise RuntimeError("FusedAdam does not support the AMSGrad variant.") + defaults = dict( + lr=lr, bias_correction=bias_correction, betas=betas, eps=eps, weight_decay=weight_decay + ) + super(FP16FusedAdam, self).__init__(params, defaults) + self.eps_mode = 0 if eps_inside_sqrt else 1 + self.FLOAT16_MAX = 65504.0 + self.init_state() + + def init_state(self): + for group in self.param_groups: + for p in group["params"]: + assert p.requires_grad == True + state = self.state[p] + if len(state) == 0: + state["step"] = 0 + # Exponential moving average of gradient values + state["exp_avg"] = torch.zeros_like(p.data) + # Exponential moving average of squared gradient values + state["exp_avg_sq"] = torch.zeros_like(p.data) + if p.data.dtype == torch.float16: + state["scale_exp_avg"] = 1.0 + state["scale_exp_avg_sq"] = 1.0 + + def step(self, closure=None, scale=1.0): + """Performs a single optimization step. Scales gradients down by scale + Arguments: + closure (callable, optional): A closure that reevaluates the model + and returns the loss. + scale (float, optional): factor to divide gradient tensor values + by before applying to weights. (default: 1) + """ + loss = None + if closure is not None: + loss = closure() + + for group in self.param_groups: + bias_correction = 1 if group["bias_correction"] else 0 + + for p in group["params"]: + if p.grad is None: + continue + grad = p.grad.data + + state = self.state[p] + + if p.data.dtype == torch.float16: + exp_avg, exp_avg_sq = ( + state["exp_avg"].float() * state["scale_exp_avg"], + state["exp_avg_sq"].float() * state["scale_exp_avg_sq"], + ) + else: + exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] + beta1, beta2 = group["betas"] + + state["step"] += 1 + + out_p = torch.tensor([], dtype=torch.float) + fused_adam_step( + p.data, + out_p, + exp_avg, + exp_avg_sq, + grad, + group["lr"], + beta1, + beta2, + group["eps"], + scale, + state["step"], + self.eps_mode, + bias_correction, + group["weight_decay"], + ) + + if p.data.dtype == torch.float16: + state["scale_exp_avg"] = ( + 1e-8 + float(torch.norm(exp_avg, float("inf"))) / self.FLOAT16_MAX + ) + state["scale_exp_avg_sq"] = ( + 1e-8 + float(torch.norm(exp_avg_sq, float("inf"))) / self.FLOAT16_MAX + ) + state["exp_avg"] = (exp_avg / state["scale_exp_avg"]).half() + state["exp_avg_sq"] = (exp_avg_sq / state["scale_exp_avg_sq"]).half() + + return loss + + +class FusedAdam(Optimizer): + def __init__( + self, + params, + lr=1e-3, + bias_correction=True, + betas=(0.9, 0.999), + eps=1e-8, + eps_inside_sqrt=False, + weight_decay=0.0, + amsgrad=False, + ): + if amsgrad: + raise RuntimeError("FusedAdam does not support the AMSGrad variant.") + defaults = dict( + lr=lr, bias_correction=bias_correction, betas=betas, eps=eps, weight_decay=weight_decay + ) + super(FusedAdam, self).__init__(params, defaults) + self.eps_mode = 0 if eps_inside_sqrt else 1 + + def step(self, closure=None, scale=1.0): + """Performs a single optimization step. Scales gradients down by scale + Arguments: + closure (callable, optional): A closure that reevaluates the model + and returns the loss. + scale (float, optional): factor to divide gradient tensor values + by before applying to weights. (default: 1) + """ + loss = None + if closure is not None: + loss = closure() + + for group in self.param_groups: + bias_correction = 1 if group["bias_correction"] else 0 + + for p in group["params"]: + if p.grad is None: + continue + grad = p.grad.data + + state = self.state[p] + + # State initialization + if len(state) == 0: + state["step"] = 0 + # Exponential moving average of gradient values + state["exp_avg"] = torch.zeros_like(p.data).float() + # Exponential moving average of squared gradient values + state["exp_avg_sq"] = torch.zeros_like(p.data).float() + + exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"] + beta1, beta2 = group["betas"] + + state["step"] += 1 + + out_p = torch.tensor([], dtype=torch.float) + fused_adam_step( + p.data, + out_p, + exp_avg, + exp_avg_sq, + grad, + group["lr"], + beta1, + beta2, + group["eps"], + scale, + state["step"], + self.eps_mode, + bias_correction, + group["weight_decay"], + ) + + return loss + diff --git a/jukebox/utils/io.py b/jukebox/utils/io.py new file mode 100644 index 0000000000000000000000000000000000000000..15ef46db96ab3d27ee85254788ef4b3c2046ecdd --- /dev/null +++ b/jukebox/utils/io.py @@ -0,0 +1,136 @@ +import numpy as np +import av +import torch as t +import jukebox.utils.dist_adapter as dist + +def get_duration_sec(file, cache=False): + try: + with open(file + '.dur', 'r') as f: + duration = float(f.readline().strip('\n')) + return duration + except: + container = av.open(file) + audio = container.streams.get(audio=0)[0] + duration = audio.duration * float(audio.time_base) + if cache: + with open(file + '.dur', 'w') as f: + f.write(str(duration) + '\n') + return duration + +def load_audio(file, sr, offset, duration, resample=True, approx=False, time_base='samples', check_duration=True): + if time_base == 'sec': + offset = offset * sr + duration = duration * sr + # Loads at target sr, stereo channels, seeks from offset, and stops after duration + container = av.open(file) + audio = container.streams.get(audio=0)[0] # Only first audio stream + audio_duration = audio.duration * float(audio.time_base) + if approx: + if offset + duration > audio_duration*sr: + # Move back one window. Cap at audio_duration + offset = np.min(audio_duration*sr - duration, offset - duration) + else: + if check_duration: + assert offset + duration <= audio_duration*sr, f'End {offset + duration} beyond duration {audio_duration*sr}' + if resample: + resampler = av.AudioResampler(format='fltp',layout='stereo', rate=sr) + else: + assert sr == audio.sample_rate + offset = int(offset / sr / float(audio.time_base)) #int(offset / float(audio.time_base)) # Use units of time_base for seeking + duration = int(duration) #duration = int(duration * sr) # Use units of time_out ie 1/sr for returning + sig = np.zeros((2, duration), dtype=np.float32) + container.seek(offset, stream=audio) + total_read = 0 + for frame in container.decode(audio=0): # Only first audio stream + if resample: + frame.pts = None + frame = resampler.resample(frame) + frame = frame.to_ndarray(format='fltp') # Convert to floats and not int16 + read = frame.shape[-1] + if total_read + read > duration: + read = duration - total_read + sig[:, total_read:total_read + read] = frame[:, :read] + total_read += read + if total_read == duration: + break + assert total_read <= duration, f'Expected {duration} frames, got {total_read}' + return sig, sr + +def test_simple_loader(): + import librosa + from tqdm import tqdm + + collate_fn = lambda batch: t.stack([t.from_numpy(b) for b in batch], dim=0) + + def get_batch(file, loader): + y1, sr = loader(file, sr=44100, offset=0.0, duration=6.0, time_base='sec') + y2, sr = loader(file, sr=44100, offset=20.0, duration=6.0, time_base='sec') + return [y1, y2] + + def load(file, loader): + batch = get_batch(file, loader) # np + x = collate_fn(batch) # torch cpu + x = x.to('cuda', non_blocking=True) # torch gpu + return x + + files = librosa.util.find_files('/root/data/', ['mp3', 'm4a', 'opus']) + print(files[:10]) + loader = load_audio + print("Loader", loader.__name__) + x = t.randn(2, 2).cuda() + x = load(files[0], loader) + for i,file in enumerate(tqdm(files)): + x = load(file, loader) + if i == 100: + break + +def test_dataset_loader(): + from tqdm import tqdm + from torch.utils.data import DataLoader + from torch.utils.data.distributed import DistributedSampler + from jukebox.utils.audio_utils import audio_preprocess, audio_postprocess + from jukebox.hparams import setup_hparams + from jukebox.data.files_dataset import FilesAudioDataset + hps = setup_hparams("teeny", {}) + hps.sr = 22050 # 44100 + hps.hop_length = 512 + hps.labels = False + hps.channels = 2 + hps.aug_shift = False + hps.bs = 2 + hps.nworkers = 2 # Getting 20 it/s with 2 workers, 10 it/s with 1 worker + print(hps) + dataset = hps.dataset + root = hps.root + from tensorboardX import SummaryWriter + sr = {22050: '22k', 44100: '44k', 48000: '48k'}[hps.sr] + writer = SummaryWriter(f'{root}/{dataset}/logs/{sr}/logs') + dataset = FilesAudioDataset(hps) + print("Length of dataset", len(dataset)) + + # Torch Loader + collate_fn = lambda batch: t.stack([t.from_numpy(b) for b in batch], 0) + sampler = DistributedSampler(dataset) + train_loader = DataLoader(dataset, batch_size=hps.bs, num_workers=hps.nworkers, pin_memory=False, sampler=sampler, + drop_last=True, collate_fn=collate_fn) + + dist.barrier() + sampler.set_epoch(0) + for i, x in enumerate(tqdm(train_loader)): + x = x.to('cuda', non_blocking=True) + for j, aud in enumerate(x): + writer.add_audio('in_' + str(i*hps.bs + j), aud, 1, hps.sr) + print("Wrote in") + x = audio_preprocess(x, hps) + x = audio_postprocess(x, hps) + for j, aud in enumerate(x): + writer.add_audio('out_' + str(i*hps.bs + j), aud, 1, hps.sr) + print("Wrote out") + dist.barrier() + break + +if __name__ == '__main__': + from jukebox.utils.dist_utils import setup_dist_from_mpi + setup_dist_from_mpi(port=29500) + test_dataset_loader() + diff --git a/jukebox/utils/logger.py b/jukebox/utils/logger.py new file mode 100644 index 0000000000000000000000000000000000000000..df6fedc16fa0b5407c1e0479f0d762df282772ea --- /dev/null +++ b/jukebox/utils/logger.py @@ -0,0 +1,147 @@ +import torch as t +import jukebox.utils.dist_adapter as dist +from tqdm import tqdm +from datetime import date +import os +import sys + +def def_tqdm(x): + return tqdm(x, leave=True, file=sys.stdout, bar_format="{n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]") + +def get_range(x): + if dist.get_rank() == 0: + return def_tqdm(x) + else: + return x + +def init_logging(hps, local_rank, rank): + logdir = f"{hps.local_logdir}/{hps.name}" + if local_rank == 0: + if not os.path.exists(logdir): + os.makedirs(logdir) + with open(logdir + 'argv.txt', 'w') as f: + f.write(hps.argv + '\n') + print("Logging to", logdir) + logger = Logger(logdir, rank) + metrics = Metrics() + logger.add_text('hps', str(hps)) + return logger, metrics + +def get_name(hps): + name = "" + for key, value in hps.items(): + name += f"{key}_{value}_" + return name + +def average_metrics(_metrics): + metrics = {} + for _metric in _metrics: + for key, val in _metric.items(): + if key not in metrics: + metrics[key] = [] + metrics[key].append(val) + return {key: sum(vals)/len(vals) for key, vals in metrics.items()} + +class Metrics: + def __init__(self): + self.sum = {} + self.n = {} + + def update(self, tag, val, batch): + # v is average value over batch + # store total value and total batch, returns dist average + sum = t.tensor(val * batch).float().cuda() + n = t.tensor(batch).float().cuda() + dist.all_reduce(sum) + dist.all_reduce(n) + sum = sum.item() + n = n.item() + self.sum[tag] = self.sum.get(tag, 0.0) + sum + self.n[tag] = self.n.get(tag, 0.0) + n + return sum / n + + def avg(self, tag): + if tag in self.sum: + return self.sum[tag] / self.n[tag] + else: + return 0.0 + + def reset(self): + self.sum = {} + self.n = {} + +class Logger: + def __init__(self, logdir, rank): + if rank == 0: + from tensorboardX import SummaryWriter + self.sw = SummaryWriter(f"{logdir}/logs") + self.iters = 0 + self.rank = rank + self.works = [] + self.logdir = logdir + + def step(self): + self.iters += 1 + + def flush(self): + if self.rank == 0: + self.sw.flush() + + def add_text(self, tag, text): + if self.rank == 0: + self.sw.add_text(tag, text, self.iters) + + def add_audios(self, tag, auds, sample_rate=22050, max_len=None, max_log=8): + if self.rank == 0: + for i in range(min(len(auds), max_log)): + if max_len: + self.sw.add_audio(f"{i}/{tag}", auds[i][:max_len * sample_rate], self.iters, sample_rate) + else: + self.sw.add_audio(f"{i}/{tag}", auds[i], self.iters, sample_rate) + + def add_audio(self, tag, aud, sample_rate=22050): + if self.rank == 0: + self.sw.add_audio(tag, aud, self.iters, sample_rate) + + def add_images(self, tag, img, dataformats="NHWC"): + if self.rank == 0: + self.sw.add_images(tag, img, self.iters, dataformats=dataformats) + + def add_image(self, tag, img): + if self.rank == 0: + self.sw.add_image(tag, img, self.iters) + + def add_scalar(self, tag, val): + if self.rank == 0: + self.sw.add_scalar(tag, val, self.iters) + + def get_range(self, loader): + if self.rank == 0: + self.trange = def_tqdm(loader) + else: + self.trange = loader + return enumerate(self.trange) + + def close_range(self): + if self.rank == 0: + self.trange.close() + + def set_postfix(self, *args, **kwargs): + if self.rank == 0: + self.trange.set_postfix(*args, **kwargs) + + # For logging summaries of varies graph ops + def add_reduce_scalar(self, tag, layer, val): + if self.iters % 100 == 0: + with t.no_grad(): + val = val.float().norm()/float(val.numel()) + work = dist.reduce(val, 0, async_op=True) + self.works.append((tag, layer, val, work)) + + def finish_reduce(self): + for tag, layer, val, work in self.works: + work.wait() + if self.rank == 0: + val = val.item()/dist.get_world_size() + self.lw[layer].add_scalar(tag, val, self.iters) + self.works = [] diff --git a/jukebox/utils/remote_utils.py b/jukebox/utils/remote_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7bdf953fb1c0a2a87f3a637fce9787e84ff696c5 --- /dev/null +++ b/jukebox/utils/remote_utils.py @@ -0,0 +1,42 @@ +import sys +import subprocess + +def download(remote_path, local_path, async_download=False): + args = ['wget', '-O', local_path, remote_path] + print("Running ", " ".join(args)) + if async_download: + subprocess.Popen(args) + else: + subprocess.call(args) + +# GCE +def gs_download(gs_path, local_path, async_download=False): + args = ['gsutil', + '-o', 'GSUtil:parallel_thread_count=1', + '-o', 'GSUtil:sliced_object_download_max_components=8', + 'cp', gs_path, local_path] + if async_download: + subprocess.Popen(args) + else: + subprocess.call(args) + + +def gs_upload(local_path, gs_path, async_upload=False): + # NOTE: Download and upload have differ -o flags. + # We also use -n to prevent clobbering checkpoints by mistake + assert not local_path.startswith("gs://") + assert gs_path.startswith("gs://") + args = ['gsutil', + '-o', 'GSUtil:parallel_composite_upload_threshold=150M', + 'cp', '-n', local_path, gs_path] + if async_upload: + subprocess.Popen(args) + else: + subprocess.call(args) + +def ls(regex): + outputs = subprocess.check_output(['gsutil', 'ls', regex]).decode(sys.stdout.encoding) + outputs = outputs.split('\n') + outputs = [output for output in outputs if output is not ''] + return outputs + diff --git a/jukebox/utils/sample_utils.py b/jukebox/utils/sample_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..0ae41b16e5dbacb5179df77d68c2923acbf54f41 --- /dev/null +++ b/jukebox/utils/sample_utils.py @@ -0,0 +1,22 @@ +import torch as t + +def split_batch(obj, n_samples, split_size): + n_passes = (n_samples + split_size - 1) // split_size + if isinstance(obj, t.Tensor): + return t.split(obj, split_size, dim=0) + elif isinstance(obj, list): + return list(zip(*[t.split(item, split_size, dim=0) for item in obj])) + elif obj is None: + return [None] * n_passes + else: + raise TypeError('Unknown input type') + +# Break total_length into hops/windows of size n_ctx separated by hop_length +def get_starts(total_length, n_ctx, hop_length): + starts = [] + for start in range(0, total_length - n_ctx + hop_length, hop_length): + if start + n_ctx >= total_length: + # Last hop could be smaller, we make it n_ctx to maximise context + start = total_length - n_ctx + starts.append(start) + return starts diff --git a/jukebox/utils/torch_utils.py b/jukebox/utils/torch_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..5d02081443ef60441593b398bede8c93d1792fec --- /dev/null +++ b/jukebox/utils/torch_utils.py @@ -0,0 +1,32 @@ +import gc +import torch as t + +def freeze_model(model): + model.eval() + for params in model.parameters(): + params.requires_grad = False + + +def unfreeze_model(model): + model.train() + for params in model.parameters(): + params.requires_grad = True + +def zero_grad(model): + for p in model.parameters(): + if p.requires_grad and p.grad is not None: + p.grad = None + +def empty_cache(): + gc.collect() + t.cuda.empty_cache() + +def assert_shape(x, exp_shape): + assert x.shape == exp_shape, f"Expected {exp_shape} got {x.shape}" + +def count_parameters(model): + return sum(p.numel() for p in model.parameters() if p.requires_grad) + +def count_state(model): + return sum(s.numel() for s in model.state_dict().values()) + diff --git a/jukebox/vqvae/__init__.py b/jukebox/vqvae/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/jukebox/vqvae/bottleneck.py b/jukebox/vqvae/bottleneck.py new file mode 100644 index 0000000000000000000000000000000000000000..18720ec528067d3efbd808ec91a272c4c28be8a4 --- /dev/null +++ b/jukebox/vqvae/bottleneck.py @@ -0,0 +1,248 @@ +import numpy as np +import torch as t +import torch.nn as nn +import torch.nn.functional as F +import jukebox.utils.dist_adapter as dist + +class BottleneckBlock(nn.Module): + def __init__(self, k_bins, emb_width, mu): + super().__init__() + self.k_bins = k_bins + self.emb_width = emb_width + self.mu = mu + self.reset_k() + self.threshold = 1.0 + + def reset_k(self): + self.init = False + self.k_sum = None + self.k_elem = None + self.register_buffer('k', t.zeros(self.k_bins, self.emb_width).cuda()) + + def _tile(self, x): + d, ew = x.shape + if d < self.k_bins: + n_repeats = (self.k_bins + d - 1) // d + std = 0.01 / np.sqrt(ew) + x = x.repeat(n_repeats, 1) + x = x + t.randn_like(x) * std + return x + + def init_k(self, x): + mu, emb_width, k_bins = self.mu, self.emb_width, self.k_bins + self.init = True + # init k_w using random vectors from x + y = self._tile(x) + _k_rand = y[t.randperm(y.shape[0])][:k_bins] + dist.broadcast(_k_rand, 0) + self.k = _k_rand + assert self.k.shape == (k_bins, emb_width) + self.k_sum = self.k + self.k_elem = t.ones(k_bins, device=self.k.device) + + def restore_k(self, num_tokens=None, threshold=1.0): + mu, emb_width, k_bins = self.mu, self.emb_width, self.k_bins + self.init = True + assert self.k.shape == (k_bins, emb_width) + self.k_sum = self.k.clone() + self.k_elem = t.ones(k_bins, device=self.k.device) + if num_tokens is not None: + expected_usage = num_tokens / k_bins + self.k_elem.data.mul_(expected_usage) + self.k_sum.data.mul_(expected_usage) + self.threshold = threshold + + def update_k(self, x, x_l): + mu, emb_width, k_bins = self.mu, self.emb_width, self.k_bins + with t.no_grad(): + # Calculate new centres + x_l_onehot = t.zeros(k_bins, x.shape[0], device=x.device) # k_bins, N * L + x_l_onehot.scatter_(0, x_l.view(1, x.shape[0]), 1) + + _k_sum = t.matmul(x_l_onehot, x) # k_bins, w + _k_elem = x_l_onehot.sum(dim=-1) # k_bins + y = self._tile(x) + _k_rand = y[t.randperm(y.shape[0])][:k_bins] + + dist.broadcast(_k_rand, 0) + dist.all_reduce(_k_sum) + dist.all_reduce(_k_elem) + + # Update centres + old_k = self.k + self.k_sum = mu * self.k_sum + (1. - mu) * _k_sum # w, k_bins + self.k_elem = mu * self.k_elem + (1. - mu) * _k_elem # k_bins + usage = (self.k_elem.view(k_bins, 1) >= self.threshold).float() + self.k = usage * (self.k_sum.view(k_bins, emb_width) / self.k_elem.view(k_bins, 1)) \ + + (1 - usage) * _k_rand + _k_prob = _k_elem / t.sum(_k_elem) # x_l_onehot.mean(dim=-1) # prob of each bin + entropy = -t.sum(_k_prob * t.log(_k_prob + 1e-8)) # entropy ie how diverse + used_curr = (_k_elem >= self.threshold).sum() + usage = t.sum(usage) + dk = t.norm(self.k - old_k) / np.sqrt(np.prod(old_k.shape)) + return dict(entropy=entropy, + used_curr=used_curr, + usage=usage, + dk=dk) + + def preprocess(self, x): + # NCT -> NTC -> [NT, C] + x = x.permute(0, 2, 1).contiguous() + x = x.view(-1, x.shape[-1]) # x_en = (N * L, w), k_j = (w, k_bins) + + if x.shape[-1] == self.emb_width: + prenorm = t.norm(x - t.mean(x)) / np.sqrt(np.prod(x.shape)) + elif x.shape[-1] == 2 * self.emb_width: + x1, x2 = x[...,:self.emb_width], x[...,self.emb_width:] + prenorm = (t.norm(x1 - t.mean(x1)) / np.sqrt(np.prod(x1.shape))) + (t.norm(x2 - t.mean(x2)) / np.sqrt(np.prod(x2.shape))) + + # Normalise + x = x1 + x2 + else: + assert False, f"Expected {x.shape[-1]} to be (1 or 2) * {self.emb_width}" + return x, prenorm + + def postprocess(self, x_l, x_d, x_shape): + # [NT, C] -> NTC -> NCT + N, T = x_shape + x_d = x_d.view(N, T, -1).permute(0, 2, 1).contiguous() + x_l = x_l.view(N, T) + return x_l, x_d + + def quantise(self, x): + # Calculate latent code x_l + k_w = self.k.t() + distance = t.sum(x ** 2, dim=-1, keepdim=True) - 2 * t.matmul(x, k_w) + t.sum(k_w ** 2, dim=0, + keepdim=True) # (N * L, b) + min_distance, x_l = t.min(distance, dim=-1) + fit = t.mean(min_distance) + return x_l, fit + + def dequantise(self, x_l): + x = F.embedding(x_l, self.k) + return x + + def encode(self, x): + N, width, T = x.shape + + # Preprocess. + x, prenorm = self.preprocess(x) + + # Quantise + x_l, fit = self.quantise(x) + + # Postprocess. + x_l = x_l.view(N, T) + return x_l + + def decode(self, x_l): + N, T = x_l.shape + width = self.emb_width + + # Dequantise + x_d = self.dequantise(x_l) + + # Postprocess + x_d = x_d.view(N, T, width).permute(0, 2, 1).contiguous() + return x_d + + def forward(self, x, update_k=True): + N, width, T = x.shape + + # Preprocess + x, prenorm = self.preprocess(x) + + # Init k if not inited + if update_k and not self.init: + self.init_k(x) + + # Quantise and dequantise through bottleneck + x_l, fit = self.quantise(x) + x_d = self.dequantise(x_l) + + # Update embeddings + if update_k: + update_metrics = self.update_k(x, x_l) + else: + update_metrics = {} + + # Loss + commit_loss = t.norm(x_d.detach() - x) ** 2 / np.prod(x.shape) + + # Passthrough + x_d = x + (x_d - x).detach() + + # Postprocess + x_l, x_d = self.postprocess(x_l, x_d, (N,T)) + return x_l, x_d, commit_loss, dict(fit=fit, + pn=prenorm, + **update_metrics) + + +class Bottleneck(nn.Module): + def __init__(self, l_bins, emb_width, mu, levels): + super().__init__() + self.levels = levels + level_block = lambda level: BottleneckBlock(l_bins, emb_width, mu) + self.level_blocks = nn.ModuleList() + for level in range(self.levels): + self.level_blocks.append(level_block(level)) + + def encode(self, xs): + zs = [level_block.encode(x) for (level_block, x) in zip(self.level_blocks, xs)] + return zs + + def decode(self, zs, start_level=0, end_level=None): + if end_level is None: + end_level = self.levels + xs_quantised = [level_block.decode(z) for (level_block, z) in zip(self.level_blocks[start_level:end_level], zs)] + return xs_quantised + + def forward(self, xs): + zs, xs_quantised, commit_losses, metrics = [], [], [], [] + for level in range(self.levels): + level_block = self.level_blocks[level] + x = xs[level] + z, x_quantised, commit_loss, metric = level_block(x, update_k=self.training) + zs.append(z) + if not self.training: + # Be extra paranoid and make sure the encoder weights can't + # change from straight-through estimator + x_quantised = x_quantised.detach() + xs_quantised.append(x_quantised) + commit_losses.append(commit_loss) + if self.training: + metrics.append(metric) + return zs, xs_quantised, commit_losses, metrics + +class NoBottleneckBlock(nn.Module): + def restore_k(self): + pass + +class NoBottleneck(nn.Module): + def __init__(self, levels): + super().__init__() + self.level_blocks = nn.ModuleList() + self.levels = levels + for level in range(levels): + self.level_blocks.append(NoBottleneckBlock()) + + def encode(self, xs): + return xs + + def decode(self, zs, start_level=0, end_level=None): + if end_level is None: + end_level = self.levels + return zs + + def forward(self, xs): + zero = t.zeros(()).cuda() + commit_losses = [zero for _ in range(self.levels)] + metrics = [dict(entropy=zero, usage=zero, used_curr=zero, pn=zero, dk=zero) for _ in range(self.levels)] + return xs, xs, commit_losses, metrics + +if __name__ == '__main__': + from jukebox.utils.dist_utils import setup_dist_from_mpi + rank, local_rank, device = setup_dist_from_mpi(port=29600) + bottleneck = Bottleneck(256, 64, 0.99, 2).to(device) + bottleneck.check() diff --git a/jukebox/vqvae/encdec.py b/jukebox/vqvae/encdec.py new file mode 100644 index 0000000000000000000000000000000000000000..ec6dd4ae8ade9c7eedf8d8a75aec29b155b183de --- /dev/null +++ b/jukebox/vqvae/encdec.py @@ -0,0 +1,131 @@ +import torch as t +import torch.nn as nn +from jukebox.vqvae.resnet import Resnet, Resnet1D +from jukebox.utils.torch_utils import assert_shape + +class EncoderConvBlock(nn.Module): + def __init__(self, input_emb_width, output_emb_width, down_t, + stride_t, width, depth, m_conv, + dilation_growth_rate=1, dilation_cycle=None, zero_out=False, + res_scale=False): + super().__init__() + blocks = [] + filter_t, pad_t = stride_t * 2, stride_t // 2 + if down_t > 0: + for i in range(down_t): + block = nn.Sequential( + nn.Conv1d(input_emb_width if i == 0 else width, width, filter_t, stride_t, pad_t), + Resnet1D(width, depth, m_conv, dilation_growth_rate, dilation_cycle, zero_out, res_scale), + ) + blocks.append(block) + block = nn.Conv1d(width, output_emb_width, 3, 1, 1) + blocks.append(block) + self.model = nn.Sequential(*blocks) + + def forward(self, x): + return self.model(x) + +class DecoderConvBock(nn.Module): + def __init__(self, input_emb_width, output_emb_width, down_t, + stride_t, width, depth, m_conv, dilation_growth_rate=1, dilation_cycle=None, zero_out=False, res_scale=False, reverse_decoder_dilation=False, checkpoint_res=False): + super().__init__() + blocks = [] + if down_t > 0: + filter_t, pad_t = stride_t * 2, stride_t // 2 + block = nn.Conv1d(output_emb_width, width, 3, 1, 1) + blocks.append(block) + for i in range(down_t): + block = nn.Sequential( + Resnet1D(width, depth, m_conv, dilation_growth_rate, dilation_cycle, zero_out=zero_out, res_scale=res_scale, reverse_dilation=reverse_decoder_dilation, checkpoint_res=checkpoint_res), + nn.ConvTranspose1d(width, input_emb_width if i == (down_t - 1) else width, filter_t, stride_t, pad_t) + ) + blocks.append(block) + self.model = nn.Sequential(*blocks) + + def forward(self, x): + return self.model(x) + +class Encoder(nn.Module): + def __init__(self, input_emb_width, output_emb_width, levels, downs_t, + strides_t, **block_kwargs): + super().__init__() + self.input_emb_width = input_emb_width + self.output_emb_width = output_emb_width + self.levels = levels + self.downs_t = downs_t + self.strides_t = strides_t + + block_kwargs_copy = dict(**block_kwargs) + if 'reverse_decoder_dilation' in block_kwargs_copy: + del block_kwargs_copy['reverse_decoder_dilation'] + level_block = lambda level, down_t, stride_t: EncoderConvBlock(input_emb_width if level == 0 else output_emb_width, + output_emb_width, + down_t, stride_t, + **block_kwargs_copy) + self.level_blocks = nn.ModuleList() + iterator = zip(list(range(self.levels)), downs_t, strides_t) + for level, down_t, stride_t in iterator: + self.level_blocks.append(level_block(level, down_t, stride_t)) + + def forward(self, x): + N, T = x.shape[0], x.shape[-1] + emb = self.input_emb_width + assert_shape(x, (N, emb, T)) + xs = [] + + # 64, 32, ... + iterator = zip(list(range(self.levels)), self.downs_t, self.strides_t) + for level, down_t, stride_t in iterator: + level_block = self.level_blocks[level] + x = level_block(x) + emb, T = self.output_emb_width, T // (stride_t ** down_t) + assert_shape(x, (N, emb, T)) + xs.append(x) + + return xs + +class Decoder(nn.Module): + def __init__(self, input_emb_width, output_emb_width, levels, downs_t, + strides_t, **block_kwargs): + super().__init__() + self.input_emb_width = input_emb_width + self.output_emb_width = output_emb_width + self.levels = levels + + self.downs_t = downs_t + + self.strides_t = strides_t + + level_block = lambda level, down_t, stride_t: DecoderConvBock(output_emb_width, + output_emb_width, + down_t, stride_t, + **block_kwargs) + self.level_blocks = nn.ModuleList() + iterator = zip(list(range(self.levels)), downs_t, strides_t) + for level, down_t, stride_t in iterator: + self.level_blocks.append(level_block(level, down_t, stride_t)) + + self.out = nn.Conv1d(output_emb_width, input_emb_width, 3, 1, 1) + + def forward(self, xs, all_levels=True): + if all_levels: + assert len(xs) == self.levels + else: + assert len(xs) == 1 + x = xs[-1] + N, T = x.shape[0], x.shape[-1] + emb = self.output_emb_width + assert_shape(x, (N, emb, T)) + + # 32, 64 ... + iterator = reversed(list(zip(list(range(self.levels)), self.downs_t, self.strides_t))) + for level, down_t, stride_t in iterator: + level_block = self.level_blocks[level] + x = level_block(x) + emb, T = self.output_emb_width, T * (stride_t ** down_t) + assert_shape(x, (N, emb, T)) + if level != 0 and all_levels: + x = x + xs[level - 1] + + x = self.out(x) + return x diff --git a/jukebox/vqvae/resnet.py b/jukebox/vqvae/resnet.py new file mode 100644 index 0000000000000000000000000000000000000000..137369e91bc2e3de5034d165dd092bb428470267 --- /dev/null +++ b/jukebox/vqvae/resnet.py @@ -0,0 +1,75 @@ +import math +import torch.nn as nn +import jukebox.utils.dist_adapter as dist +from jukebox.utils.checkpoint import checkpoint + +class ResConvBlock(nn.Module): + def __init__(self, n_in, n_state): + super().__init__() + self.model = nn.Sequential( + nn.ReLU(), + nn.Conv2d(n_in, n_state, 3, 1, 1), + nn.ReLU(), + nn.Conv2d(n_state, n_in, 1, 1, 0), + ) + + def forward(self, x): + return x + self.model(x) + +class Resnet(nn.Module): + def __init__(self, n_in, n_depth, m_conv=1.0): + super().__init__() + self.model = nn.Sequential(*[ResConvBlock(n_in, int(m_conv * n_in)) for _ in range(n_depth)]) + + def forward(self, x): + return self.model(x) + +class ResConv1DBlock(nn.Module): + def __init__(self, n_in, n_state, dilation=1, zero_out=False, res_scale=1.0): + super().__init__() + padding = dilation + self.model = nn.Sequential( + nn.ReLU(), + nn.Conv1d(n_in, n_state, 3, 1, padding, dilation), + nn.ReLU(), + nn.Conv1d(n_state, n_in, 1, 1, 0), + ) + if zero_out: + out = self.model[-1] + nn.init.zeros_(out.weight) + nn.init.zeros_(out.bias) + self.res_scale = res_scale + + def forward(self, x): + return x + self.res_scale * self.model(x) + +class Resnet1D(nn.Module): + def __init__(self, n_in, n_depth, m_conv=1.0, dilation_growth_rate=1, dilation_cycle=None, zero_out=False, res_scale=False, reverse_dilation=False, checkpoint_res=False): + super().__init__() + def _get_depth(depth): + if dilation_cycle is None: + return depth + else: + return depth % dilation_cycle + blocks = [ResConv1DBlock(n_in, int(m_conv * n_in), + dilation=dilation_growth_rate ** _get_depth(depth), + zero_out=zero_out, + res_scale=1.0 if not res_scale else 1.0 / math.sqrt(n_depth)) + for depth in range(n_depth)] + if reverse_dilation: + blocks = blocks[::-1] + self.checkpoint_res = checkpoint_res + if self.checkpoint_res == 1: + if dist.get_rank() == 0: + print("Checkpointing convs") + self.blocks = nn.ModuleList(blocks) + else: + self.model = nn.Sequential(*blocks) + + def forward(self, x): + if self.checkpoint_res == 1: + for block in self.blocks: + x = checkpoint(block, (x, ), block.parameters(), True) + return x + else: + return self.model(x) diff --git a/jukebox/vqvae/vqvae.py b/jukebox/vqvae/vqvae.py new file mode 100644 index 0000000000000000000000000000000000000000..3244b2b4535b5fe4ae35a7f83eb94a43104efd16 --- /dev/null +++ b/jukebox/vqvae/vqvae.py @@ -0,0 +1,228 @@ +import numpy as np +import torch as t +import torch.nn as nn + +from jukebox.vqvae.encdec import Encoder, Decoder, assert_shape +from jukebox.vqvae.bottleneck import NoBottleneck, Bottleneck +from jukebox.utils.logger import average_metrics +from jukebox.utils.audio_utils import spectral_convergence, spectral_loss, multispectral_loss, audio_postprocess + +def dont_update(params): + for param in params: + param.requires_grad = False + +def update(params): + for param in params: + param.requires_grad = True + +def calculate_strides(strides, downs): + return [stride ** down for stride, down in zip(strides, downs)] + +def _loss_fn(loss_fn, x_target, x_pred, hps): + if loss_fn == 'l1': + return t.mean(t.abs(x_pred - x_target)) / hps.bandwidth['l1'] + elif loss_fn == 'l2': + return t.mean((x_pred - x_target) ** 2) / hps.bandwidth['l2'] + elif loss_fn == 'linf': + residual = ((x_pred - x_target) ** 2).reshape(x_target.shape[0], -1) + values, _ = t.topk(residual, hps.linf_k, dim=1) + return t.mean(values) / hps.bandwidth['l2'] + elif loss_fn == 'lmix': + loss = 0.0 + if hps.lmix_l1: + loss += hps.lmix_l1 * _loss_fn('l1', x_target, x_pred, hps) + if hps.lmix_l2: + loss += hps.lmix_l2 * _loss_fn('l2', x_target, x_pred, hps) + if hps.lmix_linf: + loss += hps.lmix_linf * _loss_fn('linf', x_target, x_pred, hps) + return loss + else: + assert False, f"Unknown loss_fn {loss_fn}" + +class VQVAE(nn.Module): + def __init__(self, input_shape, levels, downs_t, strides_t, + emb_width, l_bins, mu, commit, spectral, multispectral, + multipliers=None, use_bottleneck=True, **block_kwargs): + super().__init__() + + self.sample_length = input_shape[0] + x_shape, x_channels = input_shape[:-1], input_shape[-1] + self.x_shape = x_shape + + self.downsamples = calculate_strides(strides_t, downs_t) + self.hop_lengths = np.cumprod(self.downsamples) + self.z_shapes = z_shapes = [(x_shape[0] // self.hop_lengths[level],) for level in range(levels)] + self.levels = levels + + if multipliers is None: + self.multipliers = [1] * levels + else: + assert len(multipliers) == levels, "Invalid number of multipliers" + self.multipliers = multipliers + def _block_kwargs(level): + this_block_kwargs = dict(block_kwargs) + this_block_kwargs["width"] *= self.multipliers[level] + this_block_kwargs["depth"] *= self.multipliers[level] + return this_block_kwargs + + encoder = lambda level: Encoder(x_channels, emb_width, level + 1, + downs_t[:level+1], strides_t[:level+1], **_block_kwargs(level)) + decoder = lambda level: Decoder(x_channels, emb_width, level + 1, + downs_t[:level+1], strides_t[:level+1], **_block_kwargs(level)) + self.encoders = nn.ModuleList() + self.decoders = nn.ModuleList() + for level in range(levels): + self.encoders.append(encoder(level)) + self.decoders.append(decoder(level)) + + if use_bottleneck: + self.bottleneck = Bottleneck(l_bins, emb_width, mu, levels) + else: + self.bottleneck = NoBottleneck(levels) + + self.downs_t = downs_t + self.strides_t = strides_t + self.l_bins = l_bins + self.commit = commit + self.spectral = spectral + self.multispectral = multispectral + + def preprocess(self, x): + # x: NTC [-1,1] -> NCT [-1,1] + assert len(x.shape) == 3 + x = x.permute(0,2,1).float() + return x + + def postprocess(self, x): + # x: NTC [-1,1] <- NCT [-1,1] + x = x.permute(0,2,1) + return x + + def _decode(self, zs, start_level=0, end_level=None): + # Decode + if end_level is None: + end_level = self.levels + assert len(zs) == end_level - start_level + xs_quantised = self.bottleneck.decode(zs, start_level=start_level, end_level=end_level) + assert len(xs_quantised) == end_level - start_level + + # Use only lowest level + decoder, x_quantised = self.decoders[start_level], xs_quantised[0:1] + x_out = decoder(x_quantised, all_levels=False) + x_out = self.postprocess(x_out) + return x_out + + def decode(self, zs, start_level=0, end_level=None, bs_chunks=1): + z_chunks = [t.chunk(z, bs_chunks, dim=0) for z in zs] + x_outs = [] + for i in range(bs_chunks): + zs_i = [z_chunk[i] for z_chunk in z_chunks] + x_out = self._decode(zs_i, start_level=start_level, end_level=end_level) + x_outs.append(x_out) + return t.cat(x_outs, dim=0) + + def _encode(self, x, start_level=0, end_level=None): + # Encode + if end_level is None: + end_level = self.levels + x_in = self.preprocess(x) + xs = [] + for level in range(self.levels): + encoder = self.encoders[level] + x_out = encoder(x_in) + xs.append(x_out[-1]) + zs = self.bottleneck.encode(xs) + return zs[start_level:end_level] + + def encode(self, x, start_level=0, end_level=None, bs_chunks=1): + x_chunks = t.chunk(x, bs_chunks, dim=0) + zs_list = [] + for x_i in x_chunks: + zs_i = self._encode(x_i, start_level=start_level, end_level=end_level) + zs_list.append(zs_i) + zs = [t.cat(zs_level_list, dim=0) for zs_level_list in zip(*zs_list)] + return zs + + def sample(self, n_samples): + zs = [t.randint(0, self.l_bins, size=(n_samples, *z_shape), device='cuda') for z_shape in self.z_shapes] + return self.decode(zs) + + def forward(self, x, hps, loss_fn='l1'): + metrics = {} + + N = x.shape[0] + + # Encode/Decode + x_in = self.preprocess(x) + xs = [] + for level in range(self.levels): + encoder = self.encoders[level] + x_out = encoder(x_in) + xs.append(x_out[-1]) + + zs, xs_quantised, commit_losses, quantiser_metrics = self.bottleneck(xs) + x_outs = [] + for level in range(self.levels): + decoder = self.decoders[level] + x_out = decoder(xs_quantised[level:level+1], all_levels=False) + assert_shape(x_out, x_in.shape) + x_outs.append(x_out) + + # Loss + def _spectral_loss(x_target, x_out, hps): + if hps.use_nonrelative_specloss: + sl = spectral_loss(x_target, x_out, hps) / hps.bandwidth['spec'] + else: + sl = spectral_convergence(x_target, x_out, hps) + sl = t.mean(sl) + return sl + + def _multispectral_loss(x_target, x_out, hps): + sl = multispectral_loss(x_target, x_out, hps) / hps.bandwidth['spec'] + sl = t.mean(sl) + return sl + + recons_loss = t.zeros(()).to(x.device) + spec_loss = t.zeros(()).to(x.device) + multispec_loss = t.zeros(()).to(x.device) + x_target = audio_postprocess(x.float(), hps) + + for level in reversed(range(self.levels)): + x_out = self.postprocess(x_outs[level]) + x_out = audio_postprocess(x_out, hps) + this_recons_loss = _loss_fn(loss_fn, x_target, x_out, hps) + this_spec_loss = _spectral_loss(x_target, x_out, hps) + this_multispec_loss = _multispectral_loss(x_target, x_out, hps) + metrics[f'recons_loss_l{level + 1}'] = this_recons_loss + metrics[f'spectral_loss_l{level + 1}'] = this_spec_loss + metrics[f'multispectral_loss_l{level + 1}'] = this_multispec_loss + recons_loss += this_recons_loss + spec_loss += this_spec_loss + multispec_loss += this_multispec_loss + + commit_loss = sum(commit_losses) + loss = recons_loss + self.spectral * spec_loss + self.multispectral * multispec_loss + self.commit * commit_loss + + with t.no_grad(): + sc = t.mean(spectral_convergence(x_target, x_out, hps)) + l2_loss = _loss_fn("l2", x_target, x_out, hps) + l1_loss = _loss_fn("l1", x_target, x_out, hps) + linf_loss = _loss_fn("linf", x_target, x_out, hps) + + quantiser_metrics = average_metrics(quantiser_metrics) + + metrics.update(dict( + recons_loss=recons_loss, + spectral_loss=spec_loss, + multispectral_loss=multispec_loss, + spectral_convergence=sc, + l2_loss=l2_loss, + l1_loss=l1_loss, + linf_loss=linf_loss, + commit_loss=commit_loss, + **quantiser_metrics)) + + for key, val in metrics.items(): + metrics[key] = val.detach() + + return x_out, loss, metrics diff --git a/requirements.txt b/requirements.txt index 295d6cf3f28e050a3712dc027b98bca416ca588c..82977d77f6888691967aaa0ad5cda96f8b504f8e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ git+https://github.com/TEAMuP-dev/pyharp.git@v0.3.0 # model-specific deps below: +setuptools<82 # madmom imports pkg_resources at runtime; removed in setuptools 82+ torch torchaudio transformers @@ -7,6 +8,17 @@ miditoolkit questionary soundfile mpi4py -sheetsage @ git+https://github.com/tanchihpin0517/PiCoGen-sheetsage.git beat_this @ https://github.com/CPJKU/beat_this/archive/main.zip -madmom @ git+https://github.com/CPJKU/madmom.git@0551aa8f48d71a367d92b5d3a347a0cf7cd97cc9 \ No newline at end of file +madmom @ git+https://github.com/CPJKU/madmom.git@0551aa8f48d71a367d92b5d3a347a0cf7cd97cc9 +# sheetsage/ and jukebox/ are vendored directly via this repo since jukebox's own +# packaging is broken upstream. Here are their runtime deps: +numpy<2 +scipy +pretty-midi +validators +pillow +fire +unidecode +numba +librosa +resampy \ No newline at end of file diff --git a/sheetsage/__init__.py b/sheetsage/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cac2db7f777432dfea4448c7e09bad5a79f29a1d --- /dev/null +++ b/sheetsage/__init__.py @@ -0,0 +1,17 @@ +import pathlib +from os import environ as os_env + +LIB_DIR = pathlib.Path(__file__).resolve().parent + +if "SHEETSAGE_CACHE_DIR" in os_env: + CACHE_DIR = pathlib.Path(os_env["SHEETSAGE_CACHE_DIR"]) +else: + CACHE_DIR = pathlib.Path(pathlib.Path.home(), ".sheetsage") +CACHE_DIR = CACHE_DIR.resolve() + + +# NOTE: This changes the test discovery pattern from "test*.py" (default) to "*test.py". +def load_tests(loader, standard_tests, pattern): + package_tests = loader.discover(start_dir=LIB_DIR, pattern="*test.py") + standard_tests.addTests(package_tests) + return standard_tests diff --git a/sheetsage/align.py b/sheetsage/align.py new file mode 100644 index 0000000000000000000000000000000000000000..b147e3fa318da88933b003048fd574304cf7b813 --- /dev/null +++ b/sheetsage/align.py @@ -0,0 +1,29 @@ +import numpy as np +from scipy.interpolate import interp1d + + +def _extrapolating_linear_interp1d(a, b, safe=True): + if safe: + if isinstance(a, np.ndarray): + a = a.tolist() + if isinstance(b, np.ndarray): + b = b.tolist() + if a != sorted(a): + raise ValueError() + if b != sorted(b): + raise ValueError() + if len(a) != len(b): + raise ValueError() + if len(np.unique(a)) != len(a): + raise ValueError() + if len(np.unique(b)) != len(b): + raise ValueError() + return interp1d(a, b, kind="linear", fill_value="extrapolate") + + +def create_beat_to_time_fn(beats, times, safe=True): + return _extrapolating_linear_interp1d(beats, times, safe=safe) + + +def create_time_to_beat_fn(beats, times, safe=True): + return _extrapolating_linear_interp1d(times, beats, safe=safe) diff --git a/sheetsage/assets.py b/sheetsage/assets.py new file mode 100644 index 0000000000000000000000000000000000000000..050bf3d5b6e65e2a53fff3f5218c53f29cffd0d4 --- /dev/null +++ b/sheetsage/assets.py @@ -0,0 +1,165 @@ +import json +import logging +import pathlib +import urllib.request + +from . import CACHE_DIR, LIB_DIR +from .utils import compute_checksum + +_DEFAULT_CHUNK_SIZE = 4096 +_ASSETS = None + + +def _init_assets(): + global _ASSETS + if _ASSETS is not None: + raise Exception("Should only run this once") + + _ASSETS = {} + asset_paths = set() + for json_path in sorted(pathlib.Path(LIB_DIR, "assets").rglob("*.json")): + with open(json_path, "r") as f: + d = json.load(f) + for tag, asset in d.items(): + if "checksum" not in asset: + raise AssertionError("Missing checksum") + try: + asset["path"] = pathlib.PurePosixPath(asset["path"].strip()) + except: + raise AssertionError("Invalid path") + if asset["path"] in asset_paths: + raise AssertionError("Duplicate path") + asset_paths.add(asset["path"]) + asset["path_abs"] = pathlib.Path(CACHE_DIR, asset["path"]) + _ASSETS.update(d) + + +_init_assets() + + +def get_asset_tags(): + return set(_ASSETS.keys()) + + +def _download(url, dest_path, chunk_size=_DEFAULT_CHUNK_SIZE): + with open(dest_path, "wb") as f: + r = urllib.request.urlopen(url) + while True: + chunk = r.read(chunk_size) + if not chunk: + break + f.write(chunk) + + +def retrieve_asset(tag, delete_wrong=False, chunk_size=_DEFAULT_CHUNK_SIZE, log=True): + """Attempts to acquire and/or verify existence of a tagged asset in the cache. + + Returns + ------- + str + Absolute file path for asset, if verified. + + Raises + ------ + :class:`ValueError` + Invalid asset tag. + :class:`Exception` + Asset could not be verified. + """ + # Retrieve asset + if tag not in _ASSETS: + raise ValueError() + asset = _ASSETS[tag] + path = asset["path_abs"] + checksum = asset["checksum"] + if log: + logging.info(f"Verifying asset: {tag}") + logging.info(f"Asset location: {path}") + + # Create parent directory + if not path.parent.is_dir(): + if log: + logging.info(f"Creating parent: {path.parent}") + path.parent.mkdir(parents=True) + + def verify(): + assert path.is_file() + if checksum is not None: + if len(checksum) == 32: + algorithm = "md5" + elif len(checksum) == 40: + algorithm = "sha1" + elif len(checksum) == 64: + algorithm = "sha256" + else: + raise AssertionError("Unknown checksum algorithm") + computed = compute_checksum( + path, algorithm=algorithm, chunk_size=chunk_size + ) + if computed != checksum: + raise Exception(f"File {path} has wrong checksum.") + + # Delete incorrect files + already_verified = False + if delete_wrong and path.is_file(): + try: + verify() + already_verified = True + except Exception: + logging.warning(f"Deleting file with bad checksum: {path}") + path.unlink() + + # Attempt to download + if not path.is_file(): + url = asset.get("url") + if url is None: + raise Exception("File is missing and cannot be downloaded") + if log: + logging.info(f"Downloading from: {url}") + try: + _download(url, path) + except Exception as e: + if path.is_file(): + path.unlink() + raise Exception(f"Download failed: {e}") + assert path.is_file() + + # Ensure file integrity + if not already_verified: + verify() + if log: + logging.info(f"Verified!") + + return path + + +if __name__ == "__main__": + import multiprocessing + from argparse import ArgumentParser + + parser = ArgumentParser() + + parser.add_argument("startswith", nargs="?") + parser.add_argument("--delete_wrong", action="store_true", dest="delete_wrong") + parser.add_argument("--num_parallel", "-n", type=int) + + parser.set_defaults(startswith=None, num_parallel=1, delete_wrong=False) + + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + tags = sorted(list(get_asset_tags())) + if args.startswith is not None: + tags = [t for t in tags if t.startswith(args.startswith.strip().upper())] + + def task(t): + logging.info("-" * 80) + try: + retrieve_asset(t, delete_wrong=args.delete_wrong) + except Exception as e: + logging.error(e) + raise e + + with multiprocessing.Pool(args.num_parallel) as p: + p.map(task, tags) diff --git a/sheetsage/assets/hooktheory.json b/sheetsage/assets/hooktheory.json new file mode 100644 index 0000000000000000000000000000000000000000..001ea34b2760c92b6c6f5e42b1ee6303eb835fb7 --- /dev/null +++ b/sheetsage/assets/hooktheory.json @@ -0,0 +1,42 @@ +{ + "HOOKTHEORY": { + "path": "hooktheory/Hooktheory.json.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory.json.gz", + "checksum": "917b7cd58f5f4e07d6c36acf7bfad958c99ee05472dab3555399141094698e0c" + }, + "HOOKTHEORY_TRAIN_SEGMENTS": { + "path": "hooktheory/Hooktheory_Train_Segments.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Train_Segments.json", + "checksum": "f2601eb544f2e5028ffad54d3827912865578fb9ad96e6768b35e4714d5c7207" + }, + "HOOKTHEORY_TRAIN_MIDI": { + "path": "hooktheory/Hooktheory_Train_MIDI.tar.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Train_MIDI.tar.gz", + "checksum": "a2345e13564c81740c087b79731b47e8323c4ceb7b85d40a1a11582af58145cb" + }, + "HOOKTHEORY_VALID_SEGMENTS": { + "path": "hooktheory/Hooktheory_Valid_Segments.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Valid_Segments.json", + "checksum": "12526962f77c2eb41cd117c8effa678b39c2b350384a7b048b327aff287b0c48" + }, + "HOOKTHEORY_VALID_MIDI": { + "path": "hooktheory/Hooktheory_Valid_MIDI.tar.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Valid_MIDI.tar.gz", + "checksum": "e369fd4a3072c7524e3cafe506bbdad6e908de969d0f1ba7abf08bf5148989fe" + }, + "HOOKTHEORY_TEST_SEGMENTS": { + "path": "hooktheory/Hooktheory_Test_Segments.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Test_Segments.json", + "checksum": "72be80045d4d28842352383e605e8712d50b3437a07b15faa541ee9d17283d5a" + }, + "HOOKTHEORY_TEST_MIDI": { + "path": "hooktheory/Hooktheory_Test_MIDI.tar.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Test_MIDI.tar.gz", + "checksum": "3baebe9d4e19a5006d0f24bc7f0c92a4f66039ab376be86bf7b37a136d4fb6c8" + }, + "HOOKTHEORY_RAW": { + "path": "hooktheory/Hooktheory_Raw.json.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/hooktheory/Hooktheory_Raw.json.gz", + "checksum": "716af2979f060400c302ab098dd45d9f8c5fe4d4b3b1fe61c478dd9bdf041634" + } +} diff --git a/sheetsage/assets/jukebox.json b/sheetsage/assets/jukebox.json new file mode 100644 index 0000000000000000000000000000000000000000..d40706e57f8330aa3685f0bc80198a931b843029 --- /dev/null +++ b/sheetsage/assets/jukebox.json @@ -0,0 +1,12 @@ +{ + "JUKEBOX_VQVAE": { + "path": "jukebox/models/5b/vqvae.pth.tar", + "url": "https://openaipublic.azureedge.net/jukebox/models/5b/vqvae.pth.tar", + "checksum": "69745413a48e887f8a3fe91b972a6f7f434021a1ce911a99187b331eb48c059a" + }, + "JUKEBOX_LM": { + "path": "jukebox/models/5b/prior_level_2.pth.tar", + "url": "https://openaipublic.azureedge.net/jukebox/models/5b/prior_level_2.pth.tar", + "checksum": "89a1dd14f5b2f9b16b3e73b53fa2138cc89fd96bb13249b4267fea471de92672" + } +} diff --git a/sheetsage/assets/rwc.json b/sheetsage/assets/rwc.json new file mode 100644 index 0000000000000000000000000000000000000000..f2073bdd490dafe2bb7bf63186080793d5d332ad --- /dev/null +++ b/sheetsage/assets/rwc.json @@ -0,0 +1,62 @@ +{ + "RWC_RYY_SEGMENTS": { + "path": "rwc/RWC_Ryy_Segments.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/rwc/RWC_Ryy_Segments.json", + "checksum": "2b7917af462615b9aa8dcc7250970f502904bc8940932457afbd44f7dd06a296" + }, + "RWC_RYY_MIDI": { + "path": "rwc/RWC_Ryy_MIDI.tar.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/rwc/RWC_Ryy_MIDI.tar.gz", + "checksum": "7ef2bbd2f6fc457f271812a706f1b7fa3d4e7e3c32572c48fb3c18737bc5af4a" + }, + "RWC_RYYVOX_SEGMENTS": { + "path": "rwc/RWC_RyyVox_Segments.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/rwc/RWC_RyyVox_Segments.json", + "checksum": "2db81af696b8e6ab5cc2af789788de80a1bb3315d4b142d3757e8385c88da002" + }, + "RWC_RYYVOX_MIDI": { + "path": "rwc/RWC_RyyVox_MIDI.tar.gz", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/rwc/RWC_RyyVox_MIDI.tar.gz", + "checksum": "7099da70a3b983036e93e99218e2c10a2ed32b36b44becc24d0299929f235ff9" + }, + "RWC_AUDIO_P012": { + "path": "rwc/audio/popular/Disc01-Track12.wav", + "checksum": "8aae6241e568d57d6d799c5a41a56d9ca94701ed3d47d88fcc8301749753e21a" + }, + "RWC_AUDIO_P038": { + "path": "rwc/audio/popular/Disc03-Track06.wav", + "checksum": "39afc8975959618b481f1dc4deaa048ba21eab93921b5ae475ab823086880bc8" + }, + "RWC_AUDIO_P060": { + "path": "rwc/audio/popular/Disc04-Track12.wav", + "checksum": "943ab44b3c88c8ad1f3d0489e05183a806da7ed238488d9e1c6d82e95ae31f06" + }, + "RWC_AUDIO_P070": { + "path": "rwc/audio/popular/Disc05-Track06.wav", + "checksum": "7bc06b86ff01075589dee396427ed27247e0c63dc0e49f6dcf44f070b3fa9bc5" + }, + "RWC_AUDIO_P079": { + "path": "rwc/audio/popular/Disc05-Track15.wav", + "checksum": "d39fb3ea61f2a52b8cdd97e2edf4bea5ea746a5a117fac8e99c42659268ef347" + }, + "RWC_AUDIO_G002": { + "path": "rwc/audio/genre/Disc01-Track02.wav", + "checksum": "aa89b13b1af9d8572c3c0c08e2fa2df54a47c382cbda3ba0bed5b47f9392f18f" + }, + "RWC_AUDIO_G010": { + "path": "rwc/audio/genre/Disc01-Track10.wav", + "checksum": "23a311a6289687e1edef94bf68a365b6498c7862847bb37ec789d57172e023c3" + }, + "RWC_AUDIO_G036": { + "path": "rwc/audio/genre/Disc03-Track09.wav", + "checksum": "c1197e8a8df39d84e9e30ed21d17ffcb14b825f87156ff07e5d6a943b8fb9193" + }, + "RWC_AUDIO_G068": { + "path": "rwc/audio/genre/Disc07-Track03.wav", + "checksum": "c41e13032bc7ca20bb214658a0e39c7715f68cd18949d106ca32477f8aa996dc" + }, + "RWC_AUDIO_G072": { + "path": "rwc/audio/genre/Disc07-Track07.wav", + "checksum": "59efe4b4ac59b373c52d92671d9417c5b217d1a3f57f5ea9eac84cf4a57a66ea" + } +} diff --git a/sheetsage/assets/sheetsage.json b/sheetsage/assets/sheetsage.json new file mode 100644 index 0000000000000000000000000000000000000000..42f8c2ccb25e1902dee18db3a27f95ac6589c403 --- /dev/null +++ b/sheetsage/assets/sheetsage.json @@ -0,0 +1,67 @@ +{ + "SHEETSAGE_V02_HANDCRAFTED_MOMENTS": { + "path": "sheetsage/v0.2/oafmelspec_moments.npy", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/oafmelspec_moments.npy", + "checksum": "81d20995052676ca4cd60afd2657c8fa0c10e21c0895b39cda85fe3f4d1255e5" + }, + "SHEETSAGE_V02_HANDCRAFTED_HARMONY_CFG": { + "path": "sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4.cfg.json", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4.cfg.json", + "checksum": "5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4" + }, + "SHEETSAGE_V02_HANDCRAFTED_HARMONY_STEP": { + "path": "sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/step.pkl", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/step.pkl", + "checksum": "06fa1073e4fea8a9af2e5560e11f67fc91b6089d218d872f0b70cad5318fd583" + }, + "SHEETSAGE_V02_HANDCRAFTED_HARMONY_MODEL": { + "path": "sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/model.pt", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_02_e0908_oafmelspecnorm/model.pt", + "checksum": "d7f6dae6902618ba285d78459010a5388002efcd685f1f2ce334297eec6c799f" + }, + "SHEETSAGE_V02_HANDCRAFTED_MELODY_CFG": { + "path": "sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/7d82e6839e582936ea428a823a0d868075a52dc5.cfg.json", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/7d82e6839e582936ea428a823a0d868075a52dc5.cfg.json", + "checksum": "7d82e6839e582936ea428a823a0d868075a52dc5" + }, + "SHEETSAGE_V02_HANDCRAFTED_MELODY_STEP": { + "path": "sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/step.pkl", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/step.pkl", + "checksum": "287bdfc444a79ebee76722726d29f57169d2170c95363ed122866ea534206006" + }, + "SHEETSAGE_V02_HANDCRAFTED_MELODY_MODEL": { + "path": "sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/model.pt", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0919_00_e0830_oafmelspecnorm/model.pt", + "checksum": "70f10a4146da8f1294597516622901d93621c5cd1bbb4e9dc831f9c43c081ef4" + }, + "SHEETSAGE_V02_JUKEBOX_HARMONY_CFG": { + "path": "sheetsage/v0.2/0920_01_e0908_jukebox53/f94f45ed03c8696f187a8bfded0f0d65476b4d48.cfg.json", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_01_e0908_jukebox53/f94f45ed03c8696f187a8bfded0f0d65476b4d48.cfg.json", + "checksum": "f94f45ed03c8696f187a8bfded0f0d65476b4d48" + }, + "SHEETSAGE_V02_JUKEBOX_HARMONY_STEP": { + "path": "sheetsage/v0.2/0920_01_e0908_jukebox53/step.pkl", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_01_e0908_jukebox53/step.pkl", + "checksum": "05f8ed82a062f152fc805dbf3e78996fa3b24d23b719ce90f4f3656e1b292a49" + }, + "SHEETSAGE_V02_JUKEBOX_HARMONY_MODEL": { + "path": "sheetsage/v0.2/0920_01_e0908_jukebox53/model.pt", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_01_e0908_jukebox53/model.pt", + "checksum": "a8d4641852c1efeae707a6fcf7d6ecddc7e2f33fa8c9753495684ae5b2e352bd" + }, + "SHEETSAGE_V02_JUKEBOX_MELODY_CFG": { + "path": "sheetsage/v0.2/0920_00_e0830_jukebox53/e968ecb8349156b2e9761ae61606454988fa614d.cfg.json", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_00_e0830_jukebox53/e968ecb8349156b2e9761ae61606454988fa614d.cfg.json", + "checksum": "e968ecb8349156b2e9761ae61606454988fa614d" + }, + "SHEETSAGE_V02_JUKEBOX_MELODY_STEP": { + "path": "sheetsage/v0.2/0920_00_e0830_jukebox53/step.pkl", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_00_e0830_jukebox53/step.pkl", + "checksum": "4443a859b4d1fd6f93a5b4351a0056522a12a771f2912b8c308e985c7a0695f1" + }, + "SHEETSAGE_V02_JUKEBOX_MELODY_MODEL": { + "path": "sheetsage/v0.2/0920_00_e0830_jukebox53/model.pt", + "url": "https://sheetsage.s3.amazonaws.com/sheetsage/v0.2/0920_00_e0830_jukebox53/model.pt", + "checksum": "e4a2cbce0a5a027e05ac753d72794ca723be2d18312f07daa0e43980d054249e" + } +} diff --git a/sheetsage/assets/test.json b/sheetsage/assets/test.json new file mode 100644 index 0000000000000000000000000000000000000000..22c924bbafc8bab7a1193a35ce1cc2d5e2b563f2 --- /dev/null +++ b/sheetsage/assets/test.json @@ -0,0 +1,47 @@ +{ + "TEST_WAV": { + "path": "test/test1_44100.wav", + "url": "https://github.com/librosa/librosa-test-data/raw/b49a879c3045ee5a54bacf62c7907915738e445d/test1_44100.wav", + "checksum": "ff8bf45609bfd5fd759af718b1e44e5544a5783c316156b6b7450ec48652718c" + }, + "TEST_MP3": { + "path": "test/test1_22050.mp3", + "url": "https://github.com/librosa/librosa-test-data/raw/b49a879c3045ee5a54bacf62c7907915738e445d/test1_22050.mp3", + "checksum": "a2084c37c252a1de25586549ef0ab5c512f8e91a2c072d5a8941817d949996b2" + }, + "TEST_MP3_OAFMELSPEC_REF": { + "path": "test/representations/oafmelspec/test_mp3_ref.npy", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/representations/oafmelspec/test_mp3_ref.npy", + "checksum": "40ed817c33f40035346e7f8f42a2712fb52d20773924bd4ebfd57a4716029ecd" + }, + "TEST_MP3_JUKEBOX_DECODE_REF": { + "path": "test/representations/jukebox/test_mp3_decode_ref.wav", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/representations/jukebox/test_mp3_decode_ref.wav", + "checksum": "152ddee1ddc4a2967213b354a4fa87818ec01b007a9b5a4808f6316b1601343d" + }, + "TEST_JUKEBOX_LEGACY": { + "path": "test/representations/jukebox/legacy.wav", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/representations/jukebox/legacy.wav", + "checksum": "728e445a61ebb2ab9cefe779a9af5c44cff39f20308a0a29bce3e3ea597aa592" + }, + "TEST_JUKEBOX_LEGACY_REF": { + "path": "test/representations/jukebox/legacy_ref.npy", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/representations/jukebox/legacy_ref.npy", + "checksum": "17eedefb640beb036acd264d37f49e7dcd11dd7636d397fa8f758e1c32dc4390" + }, + "TEST_COMMONCHORDS_JSON": { + "path": "test/theorytab/CommonChords.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/theorytab/CommonChords.json", + "checksum": "dd5e09331dcb4a4b4cfaed9d333135b7600ebea0e739491009d4d750154cfcc4" + }, + "TEST_EXAMPLEANALYSIS_JSON": { + "path": "test/theorytab/ExampleAnalysis.json", + "url": "https://github.com/chrisdonahue/sheetsage-data/raw/refs/heads/main/test/theorytab/ExampleAnalysis.json", + "checksum": "5f745055d1e2e795c87c92a764bc37712526f18f5e363eedb92cc1e8b011fa83" + }, + "TEST_FISHIN": { + "path": "test/fishin.mp3", + "url": "https://freemusicarchive.org/track/09_Lets_Go_Fishin/download/", + "checksum": "3c84bcb51aa0d44601e82e328ce07f66949b79ed919ea07ed14aa27f50a09573" + } +} diff --git a/sheetsage/beat_track.py b/sheetsage/beat_track.py new file mode 100644 index 0000000000000000000000000000000000000000..c4ffc4eb40dbde3b940351e0f6d0867fe5581400 --- /dev/null +++ b/sheetsage/beat_track.py @@ -0,0 +1,86 @@ +import math +import tempfile + +from scipy.io.wavfile import write as wavwrite + +from .utils import run_cmd_sync + + +def madmom(sr, audio, beats_per_bar=None, beats_per_minute_hint=None): + if beats_per_minute_hint is not None and beats_per_minute_hint < 0: + raise ValueError() + + # Run madmom + with tempfile.NamedTemporaryFile(suffix=".wav") as f: + wavwrite(f.name, sr, audio) + beats_per_bar_arg = "" + if beats_per_bar is not None: + if isinstance(beats_per_bar, list): + beats_per_bar_str = ",".join([str(b) for b in beats_per_bar]) + else: + beats_per_bar_str = str(beats_per_bar) + beats_per_bar_arg = f"--beats_per_bar {beats_per_bar_str}" + beats_per_minute_arg = "" + if beats_per_minute_hint is not None: + min_bpm = beats_per_minute_hint * math.pow(2, -0.5) + max_bpm = beats_per_minute_hint * math.pow(2, 0.5) + beats_per_minute_arg = f"--min_bpm {min_bpm} --max_bpm {max_bpm}" + result, stdout, stderr = run_cmd_sync( + f"DBNDownBeatTracker {beats_per_bar_arg} {beats_per_minute_arg} single {f.name}" + ) + if result != 0: + raise Exception(stderr) + + # Parse output + dbts = [] + bts = [] + for l in stdout.splitlines(): + t, p = l.split() + t = float(t) + if int(p) == 1: + dbts.append(t) + else: + bts.append(t) + + # Make sure 100Hz and convert to discrete + assert all(abs(t - (round(t * 100) / 100)) < 1e-8 for t in bts + dbts) + dbts = [round(t * 100) for t in dbts] + bts = [round(t * 100) for t in bts] + + # Sanity check (assumptions about madmom output) + assert all(t >= 0 for t in dbts + bts) + assert sorted(dbts) == dbts + assert sorted(bts) == bts + assert len(set(dbts)) == len(dbts) + assert len(set(bts)) == len(bts) + assert len(set(dbts).intersection(set(bts))) == 0 + + # Detect beats per bar + # NOTE: This logic asserts that madmom does *not* change the time signature + first_downbeat = None + detected_beats_per_bar = None + merged = sorted(dbts + bts) + if len(dbts) > 0: + first_downbeat = merged.index(dbts[0]) + partial_head = [t for t in bts if t < dbts[0]] + partial_tail = [t for t in bts if t > dbts[-1]] + detected_beats_per_bar = None + for i in range(len(dbts) - 1): + beats_this_bar = 1 + beats_this_bar += len([t for t in bts if t > dbts[i] and t < dbts[i + 1]]) + if detected_beats_per_bar is None: + detected_beats_per_bar = beats_this_bar + assert beats_this_bar == detected_beats_per_bar + assert ( + detected_beats_per_bar is None or len(partial_head) < detected_beats_per_bar + ) + assert ( + detected_beats_per_bar is None or len(partial_tail) < detected_beats_per_bar + ) + if beats_per_bar is not None and detected_beats_per_bar is not None: + if isinstance(beats_per_bar, list): + assert detected_beats_per_bar in beats_per_bar + else: + assert detected_beats_per_bar == beats_per_bar + + return first_downbeat, detected_beats_per_bar, [t / 100 for t in merged] diff --git a/sheetsage/data.py b/sheetsage/data.py new file mode 100644 index 0000000000000000000000000000000000000000..9b9385e871b9e18a1d6723a275b4b7630fced7cb --- /dev/null +++ b/sheetsage/data.py @@ -0,0 +1,288 @@ +import gzip +import json +import pathlib +import shutil +import tempfile +from enum import Enum +from io import BytesIO + +import pretty_midi + +from .align import create_beat_to_time_fn +from .assets import retrieve_asset + +_TICKS_PER_SECOND = 4096 +_QUANTIZE = lambda t: round(t * _TICKS_PER_SECOND) / _TICKS_PER_SECOND +_SEGMENT_MIDI_PITCH = 75 + + +class Split(Enum): + TRAIN = 0 + VALID = 1 + TEST = 2 + + +class HooktheoryConfig(Enum): + MELODY_TRANSCRIPTION = 0 + + +class HooktheoryAlignment(Enum): + USER = 0 + REFINED = 1 + + +class Note: + def __init__(self, onset, pitch, offset=None): + if not isinstance(onset, float): + raise TypeError() + if not isinstance(pitch, int): + raise TypeError() + if offset is not None and not isinstance(offset, float): + raise TypeError() + if onset < 0: + raise ValueError("Onset is negative") + if offset is not None and offset <= onset: + raise ValueError("Offset is before onset") + if pitch < 0 or pitch >= 128: + raise ValueError("Pitch is outside of MIDI range") + self.onset = _QUANTIZE(onset) + self.pitch = pitch + self.offset = None if offset is None else _QUANTIZE(offset) + + +class MelodyTranscriptionExample: + def __init__(self, segment_start, segment_end, melody, uid=None, audio_tag=None): + if not isinstance(segment_start, float): + raise TypeError() + if not isinstance(segment_end, float): + raise TypeError() + if not all(isinstance(n, Note) for n in melody): + raise TypeError() + if segment_start < 0: + raise ValueError("Segment start is negative") + if segment_end <= segment_start: + raise ValueError("Segment end before segment start") + + segment_start = _QUANTIZE(segment_start) + segment_end = _QUANTIZE(segment_end) + + melody = sorted(melody, key=lambda n: (n.onset, n.pitch, n.offset)) + if any((n.onset < segment_start or n.onset > segment_end) for n in melody): + raise ValueError("Onset outside of segment range") + if any( + n.offset is not None + and (n.offset < segment_start or n.offset > segment_end) + for n in melody + ): + raise ValueError("Offset outside of segment range") + for i in range(len(melody) - 1): + if melody[i].onset == melody[i + 1].onset: + raise ValueError("Simultaneous onsets detected") + if melody[i].offset is not None and melody[i].offset > melody[i + 1].onset: + raise ValueError("Notes are not monophonic") + + self.segment_start = segment_start + self.segment_end = segment_end + self.melody = melody + self.uid = uid + self.audio_tag = audio_tag + + @classmethod + def from_midi( + cls, midi, segment_start=None, segment_end=None, uid=None, audio_tag=None + ): + midi = as_pretty_midi(midi) + segment = [] + melody = [] + for i in midi.instruments: + for n in i.notes: + if i.is_drum and n.pitch == _SEGMENT_MIDI_PITCH: + segment.append(n.start) + elif not i.is_drum: + melody.append(Note(onset=n.start, pitch=n.pitch, offset=n.end)) + + if segment_start is None or segment_end is None: + if len(segment) != 2: + raise ValueError("Unknown segment") + segment_start, segment_end = sorted(segment) + + return cls( + segment_start=segment_start, + segment_end=segment_end, + melody=melody, + uid=uid, + audio_tag=audio_tag, + ) + + def to_midi(self, velocity=100): + midi = pretty_midi.PrettyMIDI(resolution=_TICKS_PER_SECOND, initial_tempo=60.0) + + segment = pretty_midi.Instrument(0, is_drum=True, name="SEGMENT") + for t in [self.segment_start, self.segment_end]: + segment.notes.append( + pretty_midi.Note( + start=t, + end=t + (1 / _TICKS_PER_SECOND), + pitch=_SEGMENT_MIDI_PITCH, + velocity=127, + ) + ) + + melody = pretty_midi.Instrument(0, name="MELODY") + for i, n in enumerate(self.melody): + offset = n.offset + if offset is None: + try: + offset = self.melody[i + 1].onset + except IndexError: + offset = n.onset + 1 + melody.notes.append( + pretty_midi.Note( + start=n.onset, end=offset, pitch=n.pitch, velocity=velocity + ) + ) + + midi.instruments = [segment, melody] + + with tempfile.NamedTemporaryFile() as f: + midi.write(f.name) + with open(f.name, "rb") as f: + return f.read() + + +_CONFIG_TO_TAGS = { + HooktheoryConfig.MELODY_TRANSCRIPTION: { + "require": ["AUDIO_AVAILABLE", "MELODY"], + # NOTE: Tempo changes are weird on Hooktheory and likely imply a bad alignment + "deny": ["TEMPO_CHANGES"], + }, +} + + +def as_pretty_midi(midi): + if isinstance(midi, bytes): + midi = pretty_midi.PrettyMIDI(BytesIO(midi)) + elif isinstance(midi, str) or isinstance(midi, pathlib.Path): + midi = pretty_midi.PrettyMIDI(str(midi)) + elif isinstance(midi, pretty_midi.PrettyMIDI): + pass + else: + raise TypeError() + return midi + + +def load_hooktheory_raw( + config=HooktheoryConfig.MELODY_TRANSCRIPTION, + alignment=HooktheoryAlignment.REFINED, + additional_required_tags=[], + additional_denied_tags=[], +): + if isinstance(config, str): + config = HooktheoryConfig[config.upper().strip()] + if isinstance(alignment, str): + alignment = HooktheoryAlignment[alignment.upper().strip()] + + # Build required tags list + require = _CONFIG_TO_TAGS[config]["require"] + require = require + additional_required_tags + if alignment is not None: + require.append( + "USER_ALIGNMENT" + if alignment == HooktheoryAlignment.USER + else "REFINED_ALIGNMENT" + ) + + # Build denied tags list + deny = _CONFIG_TO_TAGS[config]["deny"] + deny = deny + additional_denied_tags + + # Load dataset + with gzip.open(retrieve_asset("HOOKTHEORY"), "r") as f: + hooktheory = json.load(f) + + # Check tags + all_tags = set() + for attrs in hooktheory.values(): + for tag in attrs["tags"]: + all_tags.add(tag) + for tag in require + deny: + if tag not in all_tags: + raise ValueError(f"Invalid tag: {tag}") + + # Filter dataset + hooktheory = { + k: v + for k, v in hooktheory.items() + if all(tag in v["tags"] for tag in require) + and all(tag not in v["tags"] for tag in deny) + } + + return hooktheory + + +def iter_archive(archive_path): + with tempfile.TemporaryDirectory() as d: + shutil.unpack_archive(str(archive_path), d) + midi_paths = list(pathlib.Path(d).glob("*.mid*")) + uids = [p.stem for p in midi_paths] + if len(set(uids)) != len(uids): + raise ValueError("Duplicate UID") + for p in sorted(midi_paths): + yield MelodyTranscriptionExample.from_midi(p, uid=p.stem) + + +def iter_rwc_ryy(vox_only=False): + asset_tag = "RWC_RYYVOX_MIDI" if vox_only else "RWC_RYY_MIDI" + for e in iter_archive(retrieve_asset(asset_tag)): + e.audio_tag = f"RWC_AUDIO_{e.uid}" + yield e + + +def iter_hooktheory( + alignment=HooktheoryAlignment.REFINED, + split=None, + default_octave=4, + tqdm=lambda x: x, + **kwargs, +): + if isinstance(alignment, str): + alignment = HooktheoryAlignment[alignment.upper().strip()] + if isinstance(split, str): + split = Split[split.upper().strip()] + + hooktheory_raw = load_hooktheory_raw( + config=HooktheoryConfig.MELODY_TRANSCRIPTION, alignment=alignment + ) + if split is not None: + hooktheory_raw = { + k: v for k, v in hooktheory_raw.items() if v["split"] == split.name + } + + for uid, attrs in tqdm(hooktheory_raw.items()): + youtube_id = attrs["youtube"]["id"] + assert youtube_id is not None + + alignment_ = attrs["alignment"][alignment.name.lower()] + assert alignment_ is not None and len(alignment_["times"]) >= 2 + beat_to_time = create_beat_to_time_fn(alignment_["beats"], alignment_["times"]) + segment_start = float(beat_to_time(0)) + segment_end = float(beat_to_time(attrs["annotations"]["num_beats"])) + + melody = attrs["annotations"]["melody"] + assert melody is not None and len(melody) > 0 + melody = [ + Note( + onset=float(beat_to_time(n["onset"])), + pitch=(1 + default_octave + n["octave"]) * 12 + n["pitch_class"], + offset=float(beat_to_time(n["offset"])), + ) + for n in melody + ] + + yield MelodyTranscriptionExample( + uid=uid, + audio_tag=f"YOUTUBE_{youtube_id}", + segment_start=segment_start, + segment_end=segment_end, + melody=melody, + ) diff --git a/sheetsage/eval.py b/sheetsage/eval.py new file mode 100644 index 0000000000000000000000000000000000000000..02854464ea8347adb5019775fcca7fffaffbf29d --- /dev/null +++ b/sheetsage/eval.py @@ -0,0 +1,204 @@ +import copy +import logging +import pathlib +import shutil +import tempfile +import warnings +from io import BytesIO + +import mir_eval +import numpy as np +import pretty_midi + +from .data import MelodyTranscriptionExample, as_pretty_midi + +# NOTE: This is the standard alignment tolerance used in most transcription literature +EVAL_TOLERANCE = 0.050 + + +def _trim_midi(midi, segment_start, segment_end, tolerance=0): + if tolerance is not None and tolerance > 0: + segment_start -= tolerance + segment_end += tolerance + num_dropped = 0 + for i in midi.instruments: + num_notes = len(i.notes) + i.notes = [ + n for n in i.notes if n.start >= segment_start and n.start <= segment_end + ] + num_dropped += num_notes - len(i.notes) + return midi, num_dropped + + +def _midi_to_mir_eval(midi, dummy_offsets=True): + notes = [] + for i in midi.instruments: + if i.is_drum: + continue + for n in i.notes: + notes.append((n.start, n.end, n.pitch)) + notes = sorted(notes) + note_onsets = [s for s, _, _ in notes] + note_offsets = [e for _, e, _ in notes] + if dummy_offsets and len(note_onsets) > 0: + note_offsets = note_onsets[1:] + [note_onsets[-1] + 1] + intervals = np.stack([note_onsets, note_offsets], axis=1).astype(np.float64) + pitches = np.array([p for _, _, p in notes], dtype=np.int64) + return intervals, pitches + + +def _mir_eval_onset_prf( + ref_intervals, ref_pitches, est_intervals, est_pitches, tolerance=EVAL_TOLERANCE +): + m_to_f = lambda m: 440.0 * np.power(2, (m.astype(np.float32) - 69) / 12) + with warnings.catch_warnings(): + # NOTE: This function warns / returns zero when ref is empty + warnings.simplefilter("ignore") + p, r, f1, _ = mir_eval.transcription.precision_recall_f1_overlap( + ref_intervals, + m_to_f(ref_pitches), + est_intervals, + m_to_f(est_pitches), + onset_tolerance=tolerance, + pitch_tolerance=1.0, + offset_ratio=None, + ) + return p, r, f1 + + +def f1( + ref_midi, + est_midi, + tolerance=EVAL_TOLERANCE, + octave_invariant_radius=16, +): + ref_midi = as_pretty_midi(ref_midi) + est_midi = as_pretty_midi(est_midi) + + # Copy for safety + ref_midi = copy.deepcopy(ref_midi) + est_midi = copy.deepcopy(est_midi) + + # Sanity check reference MIDI + ref_example = MelodyTranscriptionExample.from_midi(ref_midi) + + # Remove drums + ref_midi.instruments = [i for i in ref_midi.instruments if not i.is_drum] + est_midi.instruments = [i for i in est_midi.instruments if not i.is_drum] + if len(est_midi.instruments) > 1: + warnings.warn(f"Multiple ({len(est_midi.instruments)}) instruments detected") + + # Trim MIDI + est_midi, num_dropped = _trim_midi( + est_midi, + ref_example.segment_start, + ref_example.segment_end, + tolerance=tolerance, + ) + if num_dropped > 0: + warnings.warn(f"{num_dropped} notes outside of segment") + + # Convert to mir_eval-style + ref_intervals, ref_pitches = _midi_to_mir_eval(ref_midi, dummy_offsets=False) + est_intervals, est_pitches = _midi_to_mir_eval(est_midi, dummy_offsets=False) + + # Octave-invariant evaluation + octaves = list(range(-octave_invariant_radius, octave_invariant_radius + 1)) + ps = [] + rs = [] + f1s = [] + for o in octaves: + p, r, f1 = _mir_eval_onset_prf( + ref_intervals, + (o * 12) + ref_pitches, + est_intervals, + est_pitches, + tolerance=tolerance, + ) + ps.append(p) + rs.append(r) + f1s.append(f1) + + best_octave_idx = np.argmax(f1s) + return ( + f1s[best_octave_idx], + ps[best_octave_idx], + rs[best_octave_idx], + octaves[best_octave_idx], + ) + + +def eval_dataset(ref, est, allow_abstain=False, return_detail=False): + ref = pathlib.Path(ref) + est = pathlib.Path(est) + detail = {} + num_abstain = 0 + with tempfile.TemporaryDirectory() as ref_dir, tempfile.TemporaryDirectory() as est_dir: + if ref.is_file(): + shutil.unpack_archive(str(ref), ref_dir) + ref = pathlib.Path(ref_dir) + if est.is_file(): + shutil.unpack_archive(str(est), est_dir) + est = pathlib.Path(est_dir) + if not ref.is_dir(): + raise Exception("Reference directory not found") + if not est.is_dir(): + raise Exception("Estimated directory not found") + + ref_uid_to_path = {p.stem: p for p in sorted(ref.glob("*.mid*"))} + est_uid_to_path = {p.stem: p for p in sorted(est.glob("*.mid*"))} + for uid, ref_path in ref_uid_to_path.items(): + est_path = est_uid_to_path.get(uid) + if est_path is None: + if allow_abstain: + num_abstain += 1 + detail[uid] = "ABSTAINED" + continue + else: + raise Exception("Abstaining not allowed") + + f1_, p, r, octave_shift = f1( + pretty_midi.PrettyMIDI(str(ref_path)), + pretty_midi.PrettyMIDI(str(est_path)), + ) + detail[uid] = {"f1": f1_, "p": p, "r": r, "octave_shift": octave_shift} + + if num_abstain > 0: + assert allow_abstain + warnings.warn(f"Abstained on {num_abstain} examples") + + f1_ = np.mean([d["f1"] for d in detail.values() if isinstance(d, dict)]) + result = f1_ + if return_detail: + result = (f1_, detail) + return result + + +if __name__ == "__main__": + import json + from argparse import ArgumentParser + + parser = ArgumentParser() + + parser.add_argument("ref_directory_or_archive", type=str) + parser.add_argument("est_directory_or_archive", type=str) + parser.add_argument("--output_path", type=str) + parser.add_argument("--allow_abstain", action="store_true") + + parser.set_defaults(output_path=None, allow_abstain=False) + + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + result, detailed = eval_dataset( + args.ref_directory_or_archive, + args.est_directory_or_archive, + return_detail=True, + allow_abstain=args.allow_abstain, + ) + logging.info(f"Overall score: {result}") + + if args.output_path is not None: + with open(args.output_path, "w") as f: + f.write(json.dumps(detailed, indent=2)) diff --git a/sheetsage/infer.py b/sheetsage/infer.py new file mode 100644 index 0000000000000000000000000000000000000000..5f5a08943e1a4ca50eac9765ff7dbd10cc6fbb58 --- /dev/null +++ b/sheetsage/infer.py @@ -0,0 +1,1087 @@ +import json +import logging +import pathlib +import tempfile +from enum import Enum +from functools import lru_cache as cache + +import numpy as np +import torch +import validators +from scipy.special import softmax + +from .align import create_beat_to_time_fn +from .assets import retrieve_asset +from .beat_track import madmom +from .modules import EncOnlyTransducer, IdentityEncoder, TransformerEncoder +from .representations import Handcrafted, Jukebox +from .theory import ( + Chord, + Harmony, + KeyChanges, + LeadSheet, + Melody, + MeterChanges, + Note, + TempoChanges, + estimate_key_changes, +) +from .utils import decode_audio, retrieve_audio_bytes + + +class InputFeats(Enum): + HANDCRAFTED = 0 + JUKEBOX = 1 + + +class Task(Enum): + MELODY = 0 + HARMONY = 1 + + +class Model(Enum): + LINEAR = 0 + TRANSFORMER = 1 + + +class Status(Enum): + FETCHING_AUDIO = 0 + DETECTING_BEATS = 1 + EXTRACTING_FEATURES = 2 + TRANSCRIBING = 3 + FORMATTING = 4 + DONE = 5 + + +_INPUT_TO_FRAME_RATE = { + InputFeats.HANDCRAFTED: 16000 / 512, + InputFeats.JUKEBOX: 44100 / 128, +} +_INPUT_TO_DIM = { + InputFeats.HANDCRAFTED: 229, + InputFeats.JUKEBOX: 4800, +} +_JUKEBOX_CHUNK_DURATION_EDGE = 23.75 +_TERTIARIES_PER_BEAT = 4 +_MELODY_PITCH_MIN = 21 +_HARMONY_FAMILIES = ["", "m", "m7", "7", "maj7", "sus", "dim", "aug"] +_FAMILY_TO_INTERVALS = { + "": (4, 3), + "m": (3, 4), + "m7": (3, 4, 3), + "7": (4, 3, 3), + "maj7": (4, 3, 4), + "sus": (5, 2), + "dim": (3, 3), + "aug": (4, 4), +} +_TASK_TO_VOCAB_SIZE = {Task.MELODY: 89, Task.HARMONY: 97} +_MAX_TERTIARIES_PER_CHUNK = 384 + + +@cache() +def _init_extractor(input_feats): + if input_feats == InputFeats.HANDCRAFTED: + extractor = Handcrafted() + elif input_feats == InputFeats.JUKEBOX: + extractor = Jukebox() + else: + raise ValueError() + return extractor + + +@cache() +def _init_model(task, input_feats, model): + if model == Model.LINEAR: + # NOTE: Just need to catalogue these configs / weights + raise NotImplementedError() + + asset_prefix = f"SHEETSAGE_V02_{input_feats.name}_{task.name}" + with open(retrieve_asset(f"{asset_prefix}_CFG", log=False), "r") as f: + cfg = json.load(f) + assert cfg["src_max_len"] == _MAX_TERTIARIES_PER_CHUNK + + src_dim = _INPUT_TO_DIM[input_feats] + output_dim = _TASK_TO_VOCAB_SIZE[task] + + if cfg["model"] == "probe": + raise RuntimeError("Probe model not supported") + model = EncOnlyTransducer( + output_dim, + src_emb_mode="identity", + src_vocab_size=None, + src_dim=src_dim, + src_emb_dim=None, + src_pos_emb=False, + src_dropout_p=0.0, + enc_cls=IdentityEncoder, + enc_kwargs={}, + ) + elif cfg["model"] == "transformer": + model = EncOnlyTransducer( + output_dim, + src_emb_mode="project", + src_vocab_size=None, + src_dim=src_dim, + src_emb_dim=512, + src_pos_emb="pos_emb" in cfg["hacks"], + src_dropout_p=0.1, + enc_cls=TransformerEncoder, + enc_kwargs={ + "model_dim": 512, + "num_heads": 8, + "num_layers": 4 if "4layers" in cfg["hacks"] else 6, + "feedforward_dim": 2048, + "dropout_p": 0.1, + }, + ) + else: + raise ValueError() + + device = torch.device("cpu") + model.to(device) + model.load_state_dict( + torch.load( + retrieve_asset(f"{asset_prefix}_MODEL", log=False), + map_location=device, + weights_only=False, + ) + ) + model.eval() + return model + + +def _closest_idx(x, l): + assert len(l) > 0 + return int(np.argmin([abs(li - x) for li in l]) + 1e-6) + + +def _beat_tracking_with_hints( + audio_path_or_bytes, + segment_start_hint, + segment_end_hint, + segment_hints_are_downbeats, + beats_per_measure_hint, + beats_per_minute_hint, + beat_detection_padding, + legacy_behavior, +): + # Decode a segment of the audio + beat_detection_start = 0.0 if segment_start_hint is None else segment_start_hint + beat_detection_start = max(beat_detection_start - beat_detection_padding, 0.0) + beat_detection_end = None if segment_end_hint is None else segment_end_hint + beat_detection_end = ( + None + if beat_detection_end is None + else beat_detection_end + beat_detection_padding + ) + if legacy_behavior: + l = segment_start_hint - beat_detection_padding + r = segment_start_hint + _JUKEBOX_CHUNK_DURATION_EDGE + beat_detection_padding + sr, audio = decode_audio(audio_path_or_bytes) + audio_duration = audio.shape[0] / sr + l, r = [round(t * sr) for t in (l, r)] + l = max(0, l) + r = min(audio.shape[0], r) + assert r > l + audio = audio[l:r] + else: + sr, audio = decode_audio( + audio_path_or_bytes, + offset=beat_detection_start, + duration=( + None + if beat_detection_end is None + else beat_detection_end - beat_detection_start + ), + ) + + # Run beat detection on segment + first_downbeat_idx, beats_per_measure, beats = madmom( + sr, + audio, + beats_per_bar=( + beats_per_measure_hint if beats_per_measure_hint is not None else [3, 4] + ), + beats_per_minute_hint=beats_per_minute_hint, + ) + if first_downbeat_idx is None or beats_per_measure is None or len(beats) == 0: + raise ValueError("Audio too short to detect time signature") + assert first_downbeat_idx >= 0 and first_downbeat_idx < beats_per_measure + assert beats_per_measure in [3, 4] + beats = [beat_detection_start + t for t in beats] + downbeats = [ + t for i, t in enumerate(beats) if i % beats_per_measure == first_downbeat_idx + ] + assert len(beats) > 0 + assert len(downbeats) > 0 + + # Convert beats into tertiary (sixteenth note) timestamps + # NOTE: Yes, this is super ugly, but sometimes you gotta do what you gotta do + beat_to_time_fn = create_beat_to_time_fn(list(range(len(beats))), beats) + tertiaries = np.arange(0, len(beats) - 1 + 1e-6, 1 / _TERTIARIES_PER_BEAT) + assert tertiaries.shape[0] == (len(beats) - 1) * _TERTIARIES_PER_BEAT + 1 + tertiaries_centered = tertiaries - (1 / _TERTIARIES_PER_BEAT) / 2 + tertiaries_times = beat_to_time_fn(tertiaries_centered) + tertiaries_times = np.maximum(tertiaries_times, 0.0) + tertiaries_times = np.minimum(tertiaries_times, beats[-1]) + + # Find first downbeat of the song from optional hint + if segment_start_hint is None: + segment_start = downbeats[0] + else: + if segment_hints_are_downbeats: + segment_start = segment_start_hint + else: + segment_start = downbeats[_closest_idx(segment_start_hint, downbeats)] + segment_start_downbeat = _closest_idx(segment_start, beats) + downbeats = [ + t + for i, t in enumerate(beats) + if i % beats_per_measure == segment_start_downbeat % beats_per_measure + ] + + # Find last downbeat of the song from optional hint + if segment_end_hint is None: + segment_end = downbeats[-1] + else: + if segment_hints_are_downbeats: + segment_end = segment_end_hint + else: + segment_end = downbeats[_closest_idx(segment_end_hint, downbeats)] + segment_end_beat = _closest_idx(segment_end, beats) + if segment_end_beat == segment_start_downbeat: + raise ValueError("Specified segment is too short (<1 measure).") + + # NOTE on naming conventions: segment_start_downbeat *is* an (internally-consistent) + # downbeat, but segment_end_beat may not be (if segment_hints_are_downbeats is true + # and user specifies an inaccurate timestamp). + + if legacy_behavior: + beats = beats[segment_start_downbeat:] + + beat_to_time_fn = create_beat_to_time_fn(list(range(len(beats))), beats) + tertiaries = np.arange(0, len(beats) + 1e-6, 1 / _TERTIARIES_PER_BEAT) + assert tertiaries.shape[0] > 0 + tertiaries -= (1 / _TERTIARIES_PER_BEAT) / 2 + tertiaries_times = beat_to_time_fn(tertiaries) + tertiaries_times = np.maximum(tertiaries_times, 0.0) + tertiaries_times = np.minimum(tertiaries_times, audio_duration) + segment_offset = tertiaries_times[0] + tertiaries_times = [ + t + for t in tertiaries_times + if t < segment_offset + _JUKEBOX_CHUNK_DURATION_EDGE + ] + segment_duration = tertiaries_times[-1] - segment_offset + tertiaries = ( + np.arange(len(tertiaries_times)) * (1 / _TERTIARIES_PER_BEAT) + ).tolist() + + segment_end_beat = ( + segment_start_downbeat + len(tertiaries) / _TERTIARIES_PER_BEAT + ) + if abs(segment_end_beat - round(segment_end_beat)) < 1e-6: + segment_end_beat = round(segment_end_beat) + else: + segment_end_beat = int(np.ceil(segment_end_beat) + 1e-6) + tertiaries = np.array(tertiaries) + tertiaries_times = np.array(tertiaries_times) + + return ( + beats_per_measure, + list(range(len(beats))), + beats, + tertiaries, + tertiaries_times, + segment_start_downbeat, + segment_end_beat, + ) + + +def _beat_parsing_with_hint( + beat_information, + segment_start_hint, + segment_end_hint, + segment_hints_are_downbeats, + beats_per_measure_hint, + beats_per_minute_hint, + beat_detection_padding, + legacy_behavior, +): + beats_times = beat_information["beats"] + beats = np.array((range(len(beats_times)))) + + beat_to_time_fn = create_beat_to_time_fn(list(range(len(beats_times))), beats_times) + tertiaries = np.arange(0, len(beats_times) - 1 + 1e-6, 1 / _TERTIARIES_PER_BEAT) + assert tertiaries.shape[0] == (len(beats_times) - 1) * _TERTIARIES_PER_BEAT + 1 + tertiaries_centered = tertiaries - (1 / _TERTIARIES_PER_BEAT) / 2 + tertiaries_times = beat_to_time_fn(tertiaries_centered) + tertiaries_times = np.maximum(tertiaries_times, 0.0) + tertiaries_times = np.minimum(tertiaries_times, beats_times[-1]) + + # NOTE: tertiaries_times does not include the last beat + downbeats_times = beat_information["downbeats"] + downbeats = [_closest_idx(t, beats_times) for t in downbeats_times] + while downbeats[-1] * _TERTIARIES_PER_BEAT >= len(tertiaries_times): + downbeats.pop() + + return beats, downbeats, beats_times, tertiaries, tertiaries_times + + +def _split_into_chunks( + tertiaries_times, + measures_per_chunk, + beats_per_measure, + segment_start_downbeat, + segment_end_beat, + avoid_chunking_if_possible, + legacy_behavior, +): + chunks = [] + + if legacy_behavior: + chunk_slice = slice(None, None) + chunk_tertiaries_times = tertiaries_times[chunk_slice] + duration = chunk_tertiaries_times[-1] - chunk_tertiaries_times[0] + assert duration > 0 and duration <= _JUKEBOX_CHUNK_DURATION_EDGE + chunks.append(chunk_slice) + else: + beats_per_chunk = beats_per_measure * measures_per_chunk + if avoid_chunking_if_possible: + chunk_start_tertiary = segment_start_downbeat * _TERTIARIES_PER_BEAT + chunk_end_tertiary = (segment_end_beat * _TERTIARIES_PER_BEAT) + 1 + chunk_slice = slice(chunk_start_tertiary, chunk_end_tertiary) + chunk_tertiaries_times = tertiaries_times[chunk_slice] + duration = chunk_tertiaries_times[-1] - chunk_tertiaries_times[0] + if duration <= _JUKEBOX_CHUNK_DURATION_EDGE: + beats_per_chunk = segment_end_beat + + for b in range(segment_start_downbeat, segment_end_beat, beats_per_chunk): + chunk_start_tertiary = b * _TERTIARIES_PER_BEAT + chunk_end_tertiary = ((b + beats_per_chunk) * _TERTIARIES_PER_BEAT) + 1 + chunk_end_tertiary = min( + chunk_end_tertiary, (segment_end_beat * _TERTIARIES_PER_BEAT) + 1 + ) + assert chunk_end_tertiary <= tertiaries_times.shape[0] + chunk_slice = slice(chunk_start_tertiary, chunk_end_tertiary) + chunk_tertiaries_times = tertiaries_times[chunk_slice] + duration = chunk_tertiaries_times[-1] - chunk_tertiaries_times[0] + assert duration > 0 + if duration > _JUKEBOX_CHUNK_DURATION_EDGE: + raise NotImplementedError( + "Dynamic chunking not implemented. Try halving measures_per_chunk." + ) + chunks.append(chunk_slice) + + return chunks + + +def _split_into_chunks_dynamicly( + tertiaries_times, + downbeats, + measures_per_chunk, + segment_start_downbeat, + segment_end_beat, +): + chunks = [] + if downbeats[0] != 0: # NOTE: include upbeat + downbeats = [0] + downbeats + chunk_start_tertiary = downbeats[0] * _TERTIARIES_PER_BEAT + accu_duration = 0 + accu_num_measures = 0 + for i in range(len(downbeats)): + measure_start_tertiary = downbeats[i] * _TERTIARIES_PER_BEAT + if i < len(downbeats) - 1: + measure_end_tertiary = downbeats[i + 1] * _TERTIARIES_PER_BEAT + 1 + else: + measure_end_tertiary = len(tertiaries_times) + # if not measure_start_tertiary < measure_end_tertiary: + # continue + assert measure_end_tertiary <= tertiaries_times.shape[0] + measure_slice = slice(measure_start_tertiary, measure_end_tertiary) + + measure_tertiaries_times = tertiaries_times[measure_slice] + accu_duration = ( + measure_tertiaries_times[-1] - tertiaries_times[chunk_start_tertiary] + ) + accu_num_measures += 1 + + if accu_duration > _JUKEBOX_CHUNK_DURATION_EDGE: + chunks.append(slice(chunk_start_tertiary, measure_start_tertiary + 1)) + chunk_start_tertiary = measure_start_tertiary + accu_duration = ( + measure_tertiaries_times[-1] - tertiaries_times[chunk_start_tertiary] + ) + accu_num_measures = 1 + + if accu_num_measures >= measures_per_chunk: + chunks.append(slice(chunk_start_tertiary, measure_end_tertiary)) + chunk_start_tertiary = measure_end_tertiary - 1 + accu_duration = 0 + accu_num_measures = 0 + + if accu_duration > _JUKEBOX_CHUNK_DURATION_EDGE: + raise ValueError( + f"Chunk duration should not exceed {_JUKEBOX_CHUNK_DURATION_EDGE} seconds. Current chunk duration: {accu_duration}." + ) + + if accu_num_measures > 0: + chunk_end_tertiary = len(tertiaries_times) + if ( + chunk_start_tertiary < chunk_end_tertiary - 1 + ): # NOTE: make sure chunk size > 1 + chunks.append(slice(chunk_start_tertiary, chunk_end_tertiary)) + + assert ( + sum([c.stop - c.start for c in chunks]) + == len(tertiaries_times) + len(chunks) - 1 + ) + + return chunks + + +def _extract_features( + audio_path_or_bytes, input_feats, tertiaries_times, chunks_tertiaries, tqdm +): + tertiary_diff_frames = np.diff(tertiaries_times) * _INPUT_TO_FRAME_RATE[input_feats] + if np.any(tertiary_diff_frames.astype(np.int64) == 0): + raise ValueError("Tempo too fast for beat-informed feature resampling") + + extractor = _init_extractor(input_feats) + chunks_features = [] + with tempfile.NamedTemporaryFile("wb") as f: + if isinstance(audio_path_or_bytes, bytes): + f.write(audio_path_or_bytes) + f.flush() + audio_path = f.name + else: + audio_path = str(audio_path_or_bytes) + + for chunk_slice in tqdm(chunks_tertiaries): + chunk_tertiaries_times = tertiaries_times[chunk_slice] + offset = chunk_tertiaries_times[0] + duration = chunk_tertiaries_times[-1] - offset + assert duration <= _JUKEBOX_CHUNK_DURATION_EDGE + fr, feats = extractor(audio_path, offset=offset, duration=duration) + beat_resampled = [] + for i in range(chunk_tertiaries_times.shape[0] - 1): + s = int((chunk_tertiaries_times[i] - offset) * fr) + e = int((chunk_tertiaries_times[i + 1] - offset) * fr) + assert e > s + beat_resampled.append(np.mean(feats[s:e], axis=0, keepdims=True)) + beat_resampled = np.concatenate(beat_resampled, axis=0) + chunks_features.append(beat_resampled) + + # Normalize handcrafted features (after beat resampling) + # NOTE: Normalizing after beat resampling is probably a bug in retrospect, but it's + # what the model expects. + if input_feats == InputFeats.HANDCRAFTED: + moments = np.load( + retrieve_asset(f"SHEETSAGE_V02_{input_feats.name}_MOMENTS", log=False) + ) + for chunk in chunks_features: + chunk -= moments[0] + chunk /= moments[1] + + return chunks_features + + +def _transcribe_chunks(chunks_features, input_feats, detect_melody, detect_harmony): + melody_logits = None + melody_last_hidden_state = None + if detect_melody: + melody_model = _init_model(Task.MELODY, input_feats, Model.TRANSFORMER) + melody_logits = [] + melody_last_hidden_state = [] + + harmony_logits = None + harmony_last_hidden_state = None + if detect_harmony: + harmony_model = _init_model(Task.HARMONY, input_feats, Model.TRANSFORMER) + harmony_logits = [] + harmony_last_hidden_state = [] + + if detect_melody or detect_harmony: + device = torch.device("cpu") + with torch.no_grad(): + for src in chunks_features: + src_len = src.shape[0] + src = np.pad(src, [(0, _MAX_TERTIARIES_PER_CHUNK - src_len), (0, 0)]) + src = src[:, np.newaxis] + src = torch.tensor(src).float() + src_len = torch.tensor(src_len).long().view(-1) + src.to(device) + src_len.to(device) + + if detect_melody: + melody_output = melody_model(src, src_len, None, None) + logits, state = ( + melody_output["logits"], + melody_output["last_hidden_state"], + ) + + logits = logits[: src_len.item(), 0] + state = state[: src_len.item(), 0] + + melody_logits.append(logits.cpu().numpy()) + melody_last_hidden_state.append(state.cpu().numpy()) + + if detect_harmony: + harmony_output = harmony_model(src, src_len, None, None) + logits, state = ( + harmony_output["logits"], + harmony_output["last_hidden_state"], + ) + + logits = logits[: src_len.item(), 0] + state = state[: src_len.item(), 0] + + harmony_logits.append(logits.cpu().numpy()) + harmony_last_hidden_state.append(state.cpu().numpy()) + + total_num_tertiary = sum([c.shape[0] for c in chunks_features]) + if detect_melody: + assert sum([c.shape[0] for c in melody_logits]) == total_num_tertiary + if detect_harmony: + assert sum([c.shape[0] for c in harmony_logits]) == total_num_tertiary + + melody_last_hidden_state = np.concatenate(melody_last_hidden_state, axis=0) + harmony_last_hidden_state = np.concatenate(harmony_last_hidden_state, axis=0) + + assert len(melody_last_hidden_state.shape) == 2 + assert len(harmony_last_hidden_state.shape) == 2 + + return ( + melody_logits, + harmony_logits, + melody_last_hidden_state, + harmony_last_hidden_state, + ) + + +def _format_lead_sheet( + melody_logits, + harmony_logits, + beats_per_measure, + beats, + beats_times, + segment_start_downbeat, + segment_end_beat, + total_num_tertiary, + melody_threshold=None, + harmony_threshold=None, +): + def decode(logits, threshold=None): + if threshold is None: + preds = np.argmax(logits, axis=-1) + else: + probs_nonnull = 1 - softmax(logits, axis=-1)[:, 0] + preds_nonnull = 1 + np.argmax(logits[:, 1:], axis=-1) + preds = np.where(probs_nonnull >= threshold, preds_nonnull, 0) + return preds + + # Decode melody + if melody_logits is None: + melody = Melody() + else: + melody_logits = np.concatenate(melody_logits, axis=0) + assert melody_logits.shape[0] == total_num_tertiary + melody_preds = decode(melody_logits, threshold=melody_threshold) + melody_onsets = [] + for o, p in enumerate(melody_preds): + if p != 0: + assert p >= 1 + p -= 1 + p = (p + _MELODY_PITCH_MIN).tolist() + melody_onsets.append((o, Note(p % 12, p // 12))) + melody = [] + for i, (o, n) in enumerate(melody_onsets): + if i + 1 < len(melody_onsets): + d = melody_onsets[i + 1][0] - o + else: + d = total_num_tertiary - o + melody.append((o, d, n)) + melody = Melody(*melody) + + # Decode harmony + if harmony_logits is None: + harmony = Harmony() + else: + harmony_logits = np.concatenate(harmony_logits, axis=0) + assert harmony_logits.shape[0] == total_num_tertiary + harmony_preds = decode(harmony_logits, threshold=harmony_threshold) + harmony = [] + last_chord = None + for o, c in enumerate(harmony_preds): + if c != 0: + assert c >= 1 + c -= 1 + c = c.tolist() + c = ( + c // len(_HARMONY_FAMILIES), + _HARMONY_FAMILIES[c % len(_HARMONY_FAMILIES)], + ) + chord = Chord(c[0], _FAMILY_TO_INTERVALS[c[1]]) + if chord != last_chord: + harmony.append((o, chord)) + last_chord = chord + harmony = Harmony(*harmony) + + # Extract tempo + measures_bps = [] + for b in range(segment_start_downbeat, segment_end_beat, beats_per_measure): + m0_time = beats_times[b] + try: + mp1_time = beats_times[b + beats_per_measure] + except IndexError: + break + assert mp1_time >= m0_time + if mp1_time > m0_time: + bps = beats_per_measure / (mp1_time - m0_time) + measures_bps.append(bps) + if len(measures_bps) > 0: + beats_per_second = np.median(measures_bps) + else: + beats_per_second = 2 + + meter_changes = MeterChanges((0, (beats_per_measure, 2, 2))) + tempo_changes = TempoChanges((0, (round(beats_per_second * 60),))) + try: + key_changes = estimate_key_changes(meter_changes, harmony, melody) + except: + # NOTE: C major by default + key_changes = KeyChanges((0, (0, (2, 2, 1, 2, 2, 2)))) + lead_sheet = LeadSheet( + meter_changes, tempo_changes, key_changes, harmony, melody, total_num_tertiary + ) + + assert beats[0] == 0 + segment_beats = [b - segment_start_downbeat for b in beats] + + return lead_sheet, segment_beats, beats_times + + +@torch.no_grad() +def sheetsage( + audio_path_bytes_or_url, + segment_start_hint=None, + segment_end_hint=None, + use_jukebox=False, + measures_per_chunk=8, + dynamic_chunking=False, + segment_hints_are_downbeats=False, + beat_information=None, + beats_per_measure_hint=None, + beats_per_minute_hint=None, + detect_melody=True, + detect_harmony=True, + melody_threshold=None, + harmony_threshold=None, + beat_detection_padding=15.0, + avoid_chunking_if_possible=True, + legacy_behavior=False, + status_change_callback=lambda s: logging.info(s.name), + return_intermediaries=False, + tqdm=lambda x: x, +): + """Main driver function for Sheet Sage: music audio -> lead sheet. + + Parameters + ---------- + audio_path_bytes_or_url : :class:`pathlib.Path`, bytes, or str + The filepath, raw bytes, or string URL of the audio to transcribe. + segment_start_hint : float or None + Approximate timestamp of start downbeat (to transcribe a segment of the audio). + segment_end_hint : float or None + Approximate timestamp of end downbeat (to transcribe a segment of the audio). + use_jukebox : bool + If True, improves transcription quality by using OpenAI Jukebox (requires GPU w/ + >=12GB VRAM). + measures_per_chunk : int + The number of measures which Sheet Sage transcribes at a time (for best results, + set to phrase length). + segment_hints_are_downbeats: bool + If True, overrides downbeat detection using the specified segment hints (note + that the hints must be *very* precise for this to work as intended). + beats_per_measure_hint : int or None + If specified, overrides time signature detection (4 for "4/4" or 3 for "3/4"). + beats_per_minute_hint : int or None + If specified, helps the beat detector find the right tempo. Useful if detected + tempo is a factor of 2 off from real tempo. + detect_melody : bool + If False, skips melody transcription. + detect_harmony : bool + If False, skips chord recognition. + melody_threshold : float + If specified, overrides default melody threshold (0-1, lower for more notes.) + harmony_threshold : float + If specified, overrides default harmony threshold (0-1, lower for more chords.) + beat_detection_padding : float + Amount of audio padding to use when running beat detection on segment. + avoid_chunking_if_possible : bool + If False, uses chunking even for segments shorter than training length. + legacy_behavior : bool + If True, ignores segment_end_hint and transcribes exactly one max-length chunk. + status_change_callback : Callable + If specified, calls this method upon changes in `Status`. + return_intermediaries : bool + If True, returns intermediate high-level results. + + Returns + ------- + :class:`sheetsage.LeadSheet` + Pass + Callable[float, float] + Metronome function for converting beat values to timestamps + """ + # Check mpi4py is installed manually + try: + from mpi4py import MPI + except ModuleNotFoundError: + raise ModuleNotFoundError( + "Please install mpi4py to use SheetSage. " + "You can install it via 'conda install mpi4py'." + ) + + if return_intermediaries: + logging.warning( + "Returning intermediate results is deprecated and will be removed in a future release." + ) + + # Check values + if segment_start_hint is not None and segment_start_hint < 0: + raise ValueError("Segment start hint cannot be negative") + if segment_end_hint is not None and segment_end_hint < 0: + raise ValueError("Segment end hint cannot be negative") + if ( + segment_start_hint is not None + and segment_end_hint is not None + and segment_end_hint <= segment_start_hint + ): + raise ValueError("Segment end hint should be greater than start hint") + if measures_per_chunk <= 0: + raise ValueError("Invalid measures per chunk specified") + if measures_per_chunk > 24: + # TODO: Allow 32 if time signature is 3/4?? + raise ValueError("Sheet Sage can only transcribe 24 measures per chunk") + if beats_per_measure_hint is not None and beats_per_measure_hint not in [3, 4]: + raise ValueError( + "Currently, Sheet Sage only supports 4/4 and 3/4 time signatures" + ) + if beat_detection_padding < 0: + raise ValueError("Beat detection padding cannot be negative") + input_feats = InputFeats.JUKEBOX if use_jukebox else InputFeats.HANDCRAFTED + + # Disambiguate between URL and file path for string inputs and retrieve URL + audio_path_or_bytes = audio_path_bytes_or_url + if isinstance(audio_path_bytes_or_url, str): + if validators.url(audio_path_bytes_or_url): + status_change_callback(Status.FETCHING_AUDIO) + logging.info(f"Retrieving audio from {audio_path_bytes_or_url}") + audio_path_or_bytes = retrieve_audio_bytes(audio_path_bytes_or_url) + else: + logging.info(f"Loading audio from {audio_path_bytes_or_url}") + audio_path_or_bytes = pathlib.Path(audio_path_bytes_or_url).resolve() + if ( + isinstance(audio_path_or_bytes, pathlib.Path) + and not audio_path_or_bytes.exists() + ): + raise FileNotFoundError(audio_path_or_bytes) + + # NOTE: If beat information is not provided, run beat detection (madmom) + if beat_information is not None: + status_change_callback(Status.DETECTING_BEATS) + ( + beats, + downbeats, + beats_times, + tertiaries, + tertiaries_times, + ) = _beat_parsing_with_hint( + beat_information, + segment_start_hint, + segment_end_hint, + segment_hints_are_downbeats, + beats_per_measure_hint, + beats_per_minute_hint, + beat_detection_padding, + legacy_behavior, + ) + beats_per_measure = None + segment_start_downbeat = None + segment_end_beat = None + else: + # TODO: Implement original beat detection + raise NotImplementedError("We haven't implemented this yet.") + # Run beat detection + status_change_callback(Status.DETECTING_BEATS) + ( + beats_per_measure, + beats, + beats_times, + tertiaries, + tertiaries_times, + segment_start_downbeat, + segment_end_beat, + ) = _beat_tracking_with_hints( + audio_path_or_bytes, + segment_start_hint, + segment_end_hint, + segment_hints_are_downbeats, + beats_per_measure_hint, + beats_per_minute_hint, + beat_detection_padding, + legacy_behavior, + ) + + # Identify suitable chunks for running through transcription model + if dynamic_chunking: + chunks_tertiaries = _split_into_chunks_dynamicly( + tertiaries_times, + downbeats, + measures_per_chunk, + segment_start_downbeat, + segment_end_beat, + ) + else: + # TODO: Implement original chunking function + raise NotImplementedError("We only support dynamic chunking for now.") + chunks_tertiaries = _split_into_chunks( + tertiaries_times, + measures_per_chunk, + beats_per_measure, + segment_start_downbeat, + segment_end_beat, + avoid_chunking_if_possible, + legacy_behavior, + ) + + # Extract features + status_change_callback(Status.EXTRACTING_FEATURES) + if use_jukebox: + logging.info("Feature extraction w/ Jukebox could take several minutes.") + chunks_features = _extract_features( + audio_path_or_bytes, input_feats, tertiaries_times, chunks_tertiaries, tqdm + ) + + # Transcribe chunks + status_change_callback(Status.TRANSCRIBING) + ( + melody_logits, + harmony_logits, + melody_last_hidden_state, + harmony_last_hidden_state, + ) = _transcribe_chunks(chunks_features, input_feats, detect_melody, detect_harmony) + + # Create lead sheet + if dynamic_chunking: + logging.warning( + "Format lead sheet for dynamic chunking is not implemented currently." + ) + lead_sheet = None + segment_beats = None + segment_beats_times = None + beats_per_measure = downbeats[1] - downbeats[0] # TODO: It's just a workaround + segment_start_downbeat = downbeats[0] + segment_end_beat = downbeats[-1] + else: + # TODO: Implement original behavior for dynamic chunking + status_change_callback(Status.FORMATTING) + total_num_tertiary = sum([c.shape[0] for c in chunks_features]) + lead_sheet, segment_beats, segment_beats_times = _format_lead_sheet( + melody_logits, + harmony_logits, + beats_per_measure, + beats, + beats_times, + segment_start_downbeat, + segment_end_beat, + total_num_tertiary, + melody_threshold=melody_threshold, + harmony_threshold=harmony_threshold, + ) + + status_change_callback(Status.DONE) + + return dict( + lead_sheet=lead_sheet, + segment_beats=segment_beats, + segment_beats_times=segment_beats_times, + chunks_tertiaries=chunks_tertiaries, + melody_logits=melody_logits, + harmony_logits=harmony_logits, + melody_last_hidden_state=melody_last_hidden_state, + harmony_last_hidden_state=harmony_last_hidden_state, + ) + + +if __name__ == "__main__": + import pathlib + import uuid + from argparse import ArgumentParser + + from tqdm import tqdm + + from .utils import engrave + + parser = ArgumentParser() + + parser.add_argument( + "audio_path_or_url", + type=str, + help="The filepath or URL of the audio to transcribe.", + ) + parser.add_argument( + "-s", + "--segment_start_hint", + type=float, + help="Approximate timestamp of start downbeat (to transcribe a segment of the audio).", + ) + parser.add_argument( + "-e", + "--segment_end_hint", + type=float, + help="Approximate timestamp of end downbeat (to transcribe a segment of the audio).", + ) + parser.add_argument( + "-t", + "--title", + type=str, + help="Title of the song.", + ) + parser.add_argument( + "-a", + "--artist", + type=str, + help="Name of the artist or composer.", + ) + parser.add_argument( + "-o", + "--output_dir", + type=str, + help="Directory to save the output files (lead sheet PDF, synchronized MIDI, etc.).", + ) + parser.add_argument( + "-j", + "--use_jukebox", + action="store_true", + help="If set, improves transcription quality by using OpenAI Jukebox (requires GPU w/ >=12GB VRAM).", + ) + parser.add_argument( + "--measures_per_chunk", + type=int, + help="The number of measures which Sheet Sage transcribes at a time (for best results, set to phrase length).", + ) + parser.add_argument( + "--segment_hints_are_downbeats", + action="store_true", + help="If set, overrides downbeat detection using the specified segment hints (note that the hints must be *very* precise for this to work as intended).", + ) + parser.add_argument( + "--beats_per_measure", + type=int, + choices=[3, 4], + help="If specified, overrides time signature detection (4 for '4/4' or 3 for '3/4').", + ) + parser.add_argument( + "--beats_per_minute_hint", + type=int, + help="If specified, helps the beat detector find the right tempo. Useful if detected tempo is a factor of 2 off from real tempo.", + ) + parser.add_argument( + "--melody_threshold", + type=float, + help="If specified, overrides default melody threshold (0-1, lower for more notes.)", + ) + parser.add_argument( + "--harmony_threshold", + type=float, + help="If specified, overrides default harmony threshold (0-1, lower for more chords.)", + ) + parser.add_argument( + "--skip_melody", + action="store_false", + dest="detect_melody", + help="If set, skips melody transcription.", + ) + parser.add_argument( + "--skip_harmony", + action="store_false", + dest="detect_harmony", + help="If set, skips chord recognition.", + ) + parser.add_argument( + "--legacy_behavior", + action="store_true", + dest="legacy_behavior", + help="If set, ignores segment_end_hint and transcribes exactly one max-length chunk.", + ) + + parser.set_defaults( + segment_start_hint=None, + segment_end_hint=None, + title=None, + artist=None, + output_dir="./output", + use_jukebox=False, + measures_per_chunk=8, + segment_hints_are_downbeats=False, + beats_per_measure=None, + beats_per_minute_hint=None, + melody_threshold=None, + harmony_threshold=None, + detect_melody=True, + detect_harmony=True, + legacy_behavior=False, + ) + + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + lead_sheet, segment_beats, segment_beats_times = sheetsage( + args.audio_path_or_url, + segment_start_hint=args.segment_start_hint, + segment_end_hint=args.segment_end_hint, + use_jukebox=args.use_jukebox, + measures_per_chunk=args.measures_per_chunk, + segment_hints_are_downbeats=args.segment_hints_are_downbeats, + beats_per_measure_hint=args.beats_per_measure, + beats_per_minute_hint=args.beats_per_minute_hint, + detect_melody=args.detect_melody, + detect_harmony=args.detect_harmony, + melody_threshold=args.melody_threshold, + harmony_threshold=args.harmony_threshold, + legacy_behavior=args.legacy_behavior, + tqdm=tqdm, + ) + + # Create output directory + output_dir = pathlib.Path(args.output_dir).resolve() + if output_dir == pathlib.Path("./output").resolve(): + uuid = uuid.uuid4().hex + output_dir = pathlib.Path(output_dir, uuid) + logging.info(f"Writing to {output_dir}") + output_dir.mkdir(parents=True, exist_ok=True) + + # Write lead sheet + lily = lead_sheet.as_lily(artist=args.artist, title=args.title) + with open(pathlib.Path(output_dir, "output.ly"), "w") as f: + f.write(lily) + with open(pathlib.Path(output_dir, "output.pdf"), "wb") as f: + f.write( + engrave( + lily, out_format="pdf", transparent=False, trim=False, hide_footer=False + ) + ) + + # Write MIDI + with open(pathlib.Path(output_dir, "output.midi"), "wb") as f: + f.write( + lead_sheet.as_midi( + pulse_to_time_fn=create_beat_to_time_fn( + segment_beats, segment_beats_times + ) + ) + ) diff --git a/sheetsage/modules/__init__.py b/sheetsage/modules/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..270dcebaa5f4e79f101903087c3dfbd8dcfdddb3 --- /dev/null +++ b/sheetsage/modules/__init__.py @@ -0,0 +1 @@ +from .modules import * diff --git a/sheetsage/modules/modules.py b/sheetsage/modules/modules.py new file mode 100644 index 0000000000000000000000000000000000000000..abec7b4e8f907a4c0321e17437a46e5e5488fb7f --- /dev/null +++ b/sheetsage/modules/modules.py @@ -0,0 +1,402 @@ +import math + +import torch +import torch.nn as nn +import torch.nn.functional as F + +# Ref: https://pytorch.org/tutorials/beginner/translation_transformer.html + + +def _xavier_init_params(params): + for p in params: + if p.dim() > 1: + torch.nn.init.xavier_uniform_(p) + + +class _PositionalEmbedding(nn.Module): + def __init__(self, emb_dim, max_len=4096): + super().__init__() + den = torch.exp(-torch.arange(0, emb_dim, 2) * math.log(10000) / emb_dim) + pos = torch.arange(0, max_len).reshape(max_len, 1) + pos_embedding = torch.zeros((max_len, emb_dim)) + pos_embedding[:, 0::2] = torch.sin(pos * den) + pos_embedding[:, 1::2] = torch.cos(pos * den) + pos_embedding = pos_embedding.unsqueeze(-2) + self.register_buffer("pos_embedding", pos_embedding) + + def forward(self, emb): + return emb + self.pos_embedding[: emb.size(0), :] + + +class _TokenEmbedding(nn.Module): + def __init__(self, vocab_size, emb_size): + super().__init__() + self.embedding = nn.Embedding(vocab_size, emb_size) + self.emb_size = emb_size + + def forward(self, tokens): + return self.embedding(tokens.long()) * math.sqrt(self.emb_size) + + +class Encoder(nn.Module): + def __init__(self, src_emb_dim): + super().__init__() + self.src_emb_dim = src_emb_dim + + def get_src_enc_dim(self): + raise NotImplementedError() + + def _encode(self, src_emb, src_len): + raise NotImplementedError() + + def forward(self, src_emb, src_len): + src_max_len, batch_size, _ = src_emb.shape + if not ( + torch.all(0 <= src_len).item() and torch.all(src_len <= src_max_len).item() + ): + raise ValueError("Invalid sequence lengths") + if src_emb.shape[-1] != self.src_emb_dim: + raise ValueError() + return self._encode(src_emb, src_len) + + +class IdentityEncoder(Encoder): + def get_src_enc_dim(self): + return self.src_emb_dim + + def _encode(self, src_emb, src_len): + return src_emb + + +class MLPEncoder(Encoder): + def __init__(self, src_emb_dim, hidden_layer_dims=[512], dropout_p=0.5): + super().__init__(src_emb_dim) + self.num_layers = len(hidden_layer_dims) + d = self.src_emb_dim + for i, ld in enumerate(hidden_layer_dims): + setattr(self, f"hidden_{i}", nn.Linear(d, ld)) + d = ld + self.output_dim = d + self.dropout = nn.Dropout(p=dropout_p) + + def get_src_enc_dim(self): + return self.output_dim + + def _encode(self, src_emb, src_len): + src_max_len, batch_size, _ = src_emb.shape + x = src_emb.view(src_max_len * batch_size, -1) + for i in range(self.num_layers): + x = getattr(self, f"hidden_{i}")(x) + x = F.relu(x) + x = self.dropout(x) + x = x.view(src_max_len, batch_size, -1) + return x + + +class TransformerEncoder(Encoder): + def __init__( + self, + src_emb_dim, + model_dim=512, + num_heads=8, + num_layers=6, + feedforward_dim=2048, + dropout_p=0.1, + _legacy_for_unit_test=False, + ): + if src_emb_dim != model_dim: + raise ValueError() + + if not _legacy_for_unit_test: + super().__init__(src_emb_dim) + + transformer_layer = nn.modules.TransformerEncoderLayer( + model_dim, + num_heads, + dim_feedforward=feedforward_dim, + dropout=dropout_p, + activation="relu", + ) + transformer_norm = nn.modules.normalization.LayerNorm(model_dim) + self.transformer = nn.modules.TransformerEncoder( + transformer_layer, num_layers, norm=transformer_norm + ) + + if not _legacy_for_unit_test: + _xavier_init_params(self.parameters()) + + self.model_dim = model_dim + + def get_src_enc_dim(self): + return self.model_dim + + def _encode(self, src_emb, src_len): + src_max_len, batch_size, _ = src_emb.shape + + # Create sequence mask + seq_idxs = torch.arange( + 0, src_max_len, dtype=src_len.dtype, device=src_emb.device + ).expand(batch_size, -1) + # NOTE: True means *do* mask that position + src_key_padding_mask = seq_idxs >= src_len.unsqueeze(1) + + return self.transformer(src_emb, src_key_padding_mask=src_key_padding_mask) + + +class Decoder(nn.Module): + def __init__(self, src_enc_dim, tgt_emb_dim): + super().__init__() + self.src_enc_dim = src_enc_dim + self.tgt_emb_dim = tgt_emb_dim + + def get_tgt_dec_dim(self): + raise NotImplementedError() + + def _decode(self, src_enc, src_len, tgt_emb, tgt_len=None): + raise NotImplementedError() + + def forward(self, src_enc, src_len, tgt_emb, tgt_len=None): + if src_enc.shape[1] != tgt_emb.shape[1]: + raise ValueError("Batch sizes must be the same") + src_max_len, batch_size, _ = src_enc.shape + tgt_max_len, _, _ = tgt_emb.shape + if not ( + torch.all(0 <= src_len).item() and torch.all(src_len <= src_max_len).item() + ): + raise ValueError("Invalid sequence lengths") + if tgt_len is not None: + if not ( + torch.all(0 <= tgt_len).item() + and torch.all(tgt_len <= tgt_max_len).item() + ): + raise ValueError("Invalid sequence lengths") + if src_enc.shape[-1] != self.src_enc_dim: + raise ValueError() + if tgt_emb.shape[-1] != self.tgt_emb_dim: + raise ValueError() + return self._decode(src_enc, src_len, tgt_emb, tgt_len=tgt_len) + + +class IdentityDecoder(Decoder): + def get_tgt_dec_dim(self): + return self.tgt_emb_dim + + def _decode(self, src_enc, src_len, tgt_emb, tgt_len=None): + return tgt_emb + + +class TransformerDecoder(Decoder): + def __init__( + self, + src_enc_dim, + tgt_emb_dim, + model_dim=512, + num_heads=8, + num_layers=6, + feedforward_dim=2048, + dropout_p=0.1, + ): + if src_enc_dim != model_dim or tgt_emb_dim != model_dim: + raise ValueError() + + super().__init__(src_enc_dim, tgt_emb_dim) + + transformer_layer = nn.modules.TransformerDecoderLayer( + model_dim, + num_heads, + dim_feedforward=feedforward_dim, + dropout=dropout_p, + activation="relu", + ) + transformer_norm = nn.modules.normalization.LayerNorm(model_dim) + self.transformer = nn.modules.TransformerDecoder( + transformer_layer, num_layers, norm=transformer_norm + ) + + _xavier_init_params(self.parameters()) + + self.model_dim = model_dim + + def get_tgt_dec_dim(self): + return self.model_dim + + def _decode(self, src_enc, src_len, tgt_emb, tgt_len=None): + src_max_len, batch_size, _ = src_enc.shape + tgt_max_len, _, _ = tgt_emb.shape + + # Create src mask (based on sequence length) + seq_idxs = torch.arange( + 0, src_max_len, dtype=src_len.dtype, device=src_enc.device + ).expand(batch_size, -1) + # NOTE: True means *do* mask that position + src_key_padding_mask = seq_idxs >= src_len.unsqueeze(1) + + # Create tgt mask (causal) + tgt_mask = ( + torch.triu( + torch.ones( + (tgt_max_len, tgt_max_len), dtype=torch.bool, device=tgt_emb.device + ) + ) + == 1 + ).transpose(0, 1) + tgt_mask = ( + tgt_mask.float() + .masked_fill(tgt_mask == 0, float("-inf")) + .masked_fill(tgt_mask == 1, float(0.0)) + ) + + return self.transformer( + tgt_emb, + src_enc, + tgt_mask=tgt_mask, + memory_key_padding_mask=src_key_padding_mask, + ) + + +class _TransducerImpl(nn.Module): + def __init__( + self, + src_emb_mode="identity", + src_vocab_size=None, + src_dim=None, + src_emb_dim=None, + src_pos_emb=False, + src_dropout_p=0, + enc_cls=IdentityEncoder, + enc_kwargs={}, + tgt_emb_mode="identity", + tgt_vocab_size=None, + tgt_dim=None, + tgt_emb_dim=None, + tgt_pos_emb=False, + tgt_dropout_p=0, + dec_cls=None, + dec_kwargs={}, + ): + super().__init__() + + # Init src embed + self.src_emb = None + if src_emb_mode == "identity": + src_emb_dim = src_dim + elif src_emb_mode == "project": + if src_dim is None or src_emb_dim is None: + raise ValueError() + self.src_emb = nn.Linear(src_dim, src_emb_dim) + elif src_emb_mode == "embed": + if src_vocab_size is None or src_emb_dim is None: + raise ValueError() + self.src_emb = _TokenEmbedding(src_vocab_size, src_emb_dim) + else: + raise ValueError() + self.src_pos_emb = None + if src_pos_emb: + if src_emb_dim is None: + raise ValueError() + self.src_pos_emb = _PositionalEmbedding(src_emb_dim) + self.src_dropout = None + if src_dropout_p > 0: + self.src_dropout = nn.Dropout(p=src_dropout_p) + + # Init encoder + self.enc = enc_cls(src_emb_dim, **enc_kwargs) + + # Init tgt embed + self.tgt_emb = None + if tgt_emb_mode == "identity": + tgt_emb_dim = tgt_dim + elif tgt_emb_mode == "project": + if tgt_dim is None or tgt_emb_dim is None: + raise ValueError() + self.tgt_emb = nn.Linear(tgt_dim, tgt_emb_dim) + elif tgt_emb_mode == "embed": + if tgt_vocab_size is None or tgt_emb_dim is None: + raise ValueError() + self.tgt_emb = _TokenEmbedding(tgt_vocab_size, tgt_emb_dim) + else: + raise ValueError() + self.tgt_pos_emb = None + if tgt_pos_emb: + if tgt_emb_dim is None: + raise ValueError() + self.tgt_pos_emb = _PositionalEmbedding(tgt_emb_dim) + self.tgt_dropout = None + if tgt_dropout_p > 0: + self.tgt_dropout = nn.Dropout(p=tgt_dropout_p) + + # Init decoder + self.dec = None + if dec_cls is not None: + self.dec = dec_cls(self.enc.get_src_enc_dim(), tgt_emb_dim, **dec_kwargs) + + def encode(self, src, src_len): + src_max_len, batch_size, _ = src.shape + + # Embed src + src_emb = src + if self.src_emb is not None: + src_emb = src_emb.view(src_max_len * batch_size, -1) + src_emb = self.src_emb(src_emb) + src_emb = src_emb.view(src_max_len, batch_size, -1) + if self.src_pos_emb is not None: + src_emb = self.src_pos_emb(src_emb) + if self.src_dropout is not None: + src_emb = self.src_dropout(src_emb) + + return self.enc(src_emb, src_len) + + def decode(self, src_enc, src_len, tgt, tgt_len=None): + if self.dec is None: + raise Exception() + + tgt_max_len, batch_size = tgt.shape + + # Embed tgt + tgt_emb = tgt + if self.tgt_emb is not None: + tgt_emb = tgt_emb.view(tgt_max_len * batch_size, -1) + tgt_emb = self.tgt_emb(tgt_emb) + tgt_emb = tgt_emb.view(tgt_max_len, batch_size, -1) + if self.tgt_pos_emb is not None: + tgt_emb = self.tgt_pos_emb(tgt_emb) + if self.tgt_dropout is not None: + tgt_emb = self.tgt_dropout(tgt_emb) + + return self.dec(src_enc, src_len, tgt_emb, tgt_len=tgt_len) + + def forward(self, src, src_len, tgt, tgt_len=None): + raise NotImplementedError() + + +class EncOnlyTransducer(_TransducerImpl): + def __init__(self, output_dim, **kwargs): + super().__init__( + tgt_emb_mode="identity", + tgt_vocab_size=None, + tgt_dim=None, + tgt_emb_dim=None, + tgt_pos_emb=False, + dec_cls=None, + dec_kwargs={}, + **kwargs, + ) + self.output = nn.Linear(self.enc.get_src_enc_dim(), output_dim) + + def decode(self, src_enc, src_len, tgt, tgt_len=None): + raise Exception() + + def forward(self, src, src_len, tgt=None, tgt_len=None): + src_max_len, batch_size, _ = src.shape + + src_enc = self.encode(src, src_len) + + out = src_enc + out = out.view(src_max_len * batch_size, -1) + out = self.output(out) + out = out.view(src_max_len, batch_size, -1) + + return dict( + logits=out, + last_hidden_state=src_enc, + ) diff --git a/sheetsage/representations/__init__.py b/sheetsage/representations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5652f63edea621c445fa982113f8134f03f31376 --- /dev/null +++ b/sheetsage/representations/__init__.py @@ -0,0 +1,10 @@ +import numpy as np + +from ..assets import retrieve_asset +from .handcrafted import OAFMelSpec as Handcrafted +from .jukebox import Jukebox as _Jukebox + + +class Jukebox(_Jukebox): + def __init__(self): + super().__init__(num_layers=53, fp16=False, log=False) diff --git a/sheetsage/representations/base.py b/sheetsage/representations/base.py new file mode 100644 index 0000000000000000000000000000000000000000..674071578451114b41274e7b820c9cb42342164a --- /dev/null +++ b/sheetsage/representations/base.py @@ -0,0 +1,4 @@ +class Representation: + def __call__(self, audio_path, offset=0.0, duration=None): + # NOTE: Should return tuple containing (rate: float, features: np.ndarray) + raise NotImplementedError() diff --git a/sheetsage/representations/handcrafted.py b/sheetsage/representations/handcrafted.py new file mode 100644 index 0000000000000000000000000000000000000000..b2522cbac5c5715e4a2636e1012105652d45ade6 --- /dev/null +++ b/sheetsage/representations/handcrafted.py @@ -0,0 +1,43 @@ +import pickle + +import librosa +import numpy as np + +from ..utils import decode_audio +from .base import Representation + + +class OAFMelSpec(Representation): + # NOTE: This configuration is from Onsets & Frames (Hawthorne et al. 17). + # https://github.com/magenta/magenta/blob/9885adef56d134763a89de5584f7aa18ca7d53b6/magenta/models/onsets_frames_transcription/constants.py + # https://github.com/magenta/magenta/blob/9885adef56d134763a89de5584f7aa18ca7d53b6/magenta/models/onsets_frames_transcription/data.py#L89 + _SR = 16000 + _NFFT = 2048 + _HOP_SIZE = 512 + _FMIN = 30.0 + _NMELS = 229 + _HTK = False + _LOG = True + + def __call__(self, audio_path, offset=0.0, duration=None): + sr, audio = decode_audio( + audio_path, + sr=self._SR, + offset=offset, + duration=duration, + mono=True, + normalize=False, + ) + features = librosa.feature.melspectrogram( + y=audio[:, 0], + sr=self._SR, + n_fft=self._NFFT, + hop_length=self._HOP_SIZE, + fmin=self._FMIN, + n_mels=self._NMELS, + htk=self._HTK, + ).T + features = features.astype(np.float32) + if self._LOG: + features = librosa.power_to_db(features) + return self._SR / self._HOP_SIZE, features diff --git a/sheetsage/representations/jukebox.py b/sheetsage/representations/jukebox.py new file mode 100644 index 0000000000000000000000000000000000000000..32338f776a3e8d978c518584be727910029cd876 --- /dev/null +++ b/sheetsage/representations/jukebox.py @@ -0,0 +1,241 @@ +import io +import logging +import warnings +from contextlib import redirect_stdout + +import jukebox.hparams +import jukebox.make_models +import jukebox.utils.dist_utils +import librosa +import numpy as np +import torch + +from ..utils import decode_audio, get_approximate_audio_length +from .base import Representation + +_SAMPLE_RATE = 44100 +_FRAME_HOP_SIZE = 128 +_MIN_LENGTH_SAMPLES = (60 * _SAMPLE_RATE) + 16 +_MAX_LENGTH_SAMPLES = (600 * _SAMPLE_RATE) - 96 +_CHUNK_FRAMES = 8192 +_CHUNK_SAMPLES = _CHUNK_FRAMES * _FRAME_HOP_SIZE + +_SINGLETON = None + + +def init_jukebox_singleton(model="5b", num_layers=53, log=True): + global _SINGLETON + + if _SINGLETON is None: + # Set up device + with redirect_stdout(io.StringIO()) as s: + rank, local_rank, device = jukebox.utils.dist_utils.setup_dist_from_mpi() + if log: + logging.info(s.getvalue()) + + # Set up hyperparams + hps = jukebox.hparams.Hyperparams() + hps.sr = _SAMPLE_RATE + hps.n_samples = 3 if model == "5b_lyrics" else 8 + hps.name = "samples" + chunk_size = 16 if model == "5b_lyrics" else 32 + max_batch_size = 3 if model == "5b_lyrics" else 16 + hps.levels = 3 + hps.hop_fraction = [0.5, 0.5, 0.125] + + # Load VQVAE + vqvae, *priors = jukebox.make_models.MODELS[model] + with redirect_stdout(io.StringIO()) as s: + vqvae = jukebox.make_models.make_vqvae( + jukebox.hparams.setup_hparams( + vqvae, dict(sample_length=_CHUNK_SAMPLES) + ), + device, + ) + if log: + logging.info(s.getvalue()) + + # Set up language model + if num_layers is not None: + overrides = dict(prior_depth=num_layers) + else: + overrides = dict() + with redirect_stdout(io.StringIO()) as s: + lm = jukebox.make_models.make_prior( + jukebox.hparams.setup_hparams(priors[-1], overrides), vqvae, device + ) + if log: + logging.info(s.getvalue()) + lm.prior.only_encode = True + + _SINGLETON = (model, num_layers, hps, vqvae, lm, device) + else: + if (model, num_layers) != _SINGLETON[:2]: + raise Exception("Jukebox can only be initialized once") + + return _SINGLETON + + +class Jukebox(Representation): + def __init__(self, num_layers=53, fp16=False, log=True): + # NOTE: Layer 53 is the deepest that fit on a commodity 12GB card + ( + _, + _, + self.hps, + self.vqvae, + self.lm, + self.device, + ) = init_jukebox_singleton(model="5b", num_layers=num_layers, log=log) + self.fp16 = fp16 + + @classmethod + def decode_audio(cls, audio_path, offset=0.0, duration=None): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + audio, sr = librosa.load( + audio_path, sr=None, mono=False, offset=offset, duration=duration + ) + if audio.ndim == 1: + audio = audio[np.newaxis, :] + audio = np.swapaxes(audio, 0, 1) + audio = np.mean(audio, axis=1, keepdims=False) + if sr != _SAMPLE_RATE: + audio = librosa.resample(audio, orig_sr=sr, target_sr=_SAMPLE_RATE, res_type="kaiser_best") + if audio.shape[0] > 0: + norm_factor = np.abs(audio).max() + if norm_factor > 0: + audio /= norm_factor + return audio + + def _codify_audio( + self, audio, tqdm=lambda x: x, window_size=_CHUNK_SAMPLES, pad=True + ): + # NOTE: Ugly API for legacy test case. + hop_size = _CHUNK_SAMPLES + hop_size_frames = window_size // _FRAME_HOP_SIZE + result = [] + for i in tqdm(list(range(0, audio.shape[0], hop_size))): + context = audio[i : i + window_size] + if pad and context.shape[0] < window_size: + context = np.pad(context, (0, window_size - context.shape[0])) + with torch.no_grad(): + context = torch.tensor( + context, dtype=torch.float32, device=self.device + ).view(1, -1, 1) + context_codified = self.vqvae.encode(context)[-1].view(-1).cpu().numpy() + context_codified = context_codified[:hop_size_frames] + result.append(context_codified) + return np.concatenate(result, axis=0) + + def codify_audio(self, audio, tqdm=lambda x: x): + return self._codify_audio(audio, tqdm=tqdm) + + def lm_activations( + self, + audio_codified, + metadata_offset_seconds=0.0, + metadata_total_length_seconds=None, + metadata_artist=None, + metadata_genre=None, + metadata_lyrics=None, + tqdm=lambda x: x, + ): + hop_size = _CHUNK_FRAMES + window_size = _CHUNK_FRAMES + if audio_codified.shape[0] % _CHUNK_FRAMES != 0: + raise ValueError() + + # Compute metadata offset + metadata_initial_offset = int(metadata_offset_seconds * _SAMPLE_RATE) + metadata_initial_offset = ( + metadata_initial_offset // _FRAME_HOP_SIZE + ) * _FRAME_HOP_SIZE + assert metadata_initial_offset % _FRAME_HOP_SIZE == 0 + if metadata_initial_offset < 0: + raise ValueError() + + # Compute metadata total length + if metadata_total_length_seconds is None: + metadata_total_length = audio_codified.shape[0] * _FRAME_HOP_SIZE + else: + metadata_total_length = int(metadata_total_length_seconds * _SAMPLE_RATE) + metadata_total_length = max(metadata_total_length, _MIN_LENGTH_SAMPLES) + metadata_total_length = min(metadata_total_length, _MAX_LENGTH_SAMPLES) + metadata_total_length = ( + metadata_total_length // _FRAME_HOP_SIZE + ) * _FRAME_HOP_SIZE + assert metadata_total_length % _FRAME_HOP_SIZE == 0 + assert metadata_total_length >= _MIN_LENGTH_SAMPLES + assert metadata_total_length <= _MAX_LENGTH_SAMPLES + + result = [] + for i in tqdm(list(range(0, audio_codified.shape[0], hop_size))): + # Select context window + context = audio_codified[i : i + window_size] + metadata_offset = metadata_initial_offset + i * _FRAME_HOP_SIZE + metadata_offset = min( + metadata_offset, + metadata_total_length - (context.shape[0] * _FRAME_HOP_SIZE), + ) + metadata_offset = max(metadata_offset, 0) + assert metadata_offset % _FRAME_HOP_SIZE == 0 + + with torch.no_grad(): + # Context + x = torch.tensor(context, dtype=torch.int64, device=self.device).view( + 1, -1 + ) + + # Conditioning info + meta = dict( + artist="unknown" if metadata_artist is None else metadata_artist, + genre="unknown" if metadata_genre is None else metadata_genre, + total_length=metadata_total_length, + offset=metadata_offset, + lyrics="Placeholder lyrics which do not affect 5b" + if metadata_lyrics is None + else metadata_lyrics, + ) + metas = [meta] * self.hps.n_samples + labels = [None, None, self.lm.labeller.get_batch_labels(metas, "cuda")] + x_cond, y_cond, _ = self.lm.get_cond(None, self.lm.get_y(labels[-1], 0)) + x_cond = x_cond[:1] + y_cond = y_cond[:1] + + # Extract activations + activations = ( + self.lm.prior.forward( + x, x_cond=x_cond, y_cond=y_cond, fp16=self.fp16 + ) + .cpu() + .numpy() + ) + if self.fp16: + activations = activations.astype(np.float16) + result.append(activations[0]) + + # Clear memory + del x + del labels + del x_cond + del y_cond + torch.cuda.empty_cache() + + return np.concatenate(result, axis=0) + + def __call__(self, audio_path, offset=0.0, duration=None): + audio = self.decode_audio(audio_path, offset=offset, duration=duration) + if offset == 0.0 and duration is None: + total_length = audio.shape[0] / _SAMPLE_RATE + else: + total_length = get_approximate_audio_length(audio_path) + codified_audio = self.codify_audio(audio) + activations = self.lm_activations( + codified_audio, + metadata_offset_seconds=offset, + metadata_total_length_seconds=total_length, + ) + activations = activations[: int(audio.shape[0] / _FRAME_HOP_SIZE)] + rate = _SAMPLE_RATE / _FRAME_HOP_SIZE + return rate, activations diff --git a/sheetsage/serve/backend/main.py b/sheetsage/serve/backend/main.py new file mode 100644 index 0000000000000000000000000000000000000000..7e900e7426e3534bc92e08e57c46434d18f605eb --- /dev/null +++ b/sheetsage/serve/backend/main.py @@ -0,0 +1,342 @@ +import json +import multiprocessing +import pathlib +import traceback +from enum import Enum + +from flask import Flask, abort, jsonify, request, send_file + +from ...infer import Status as SheetSageStatus +from ...infer import sheetsage +from ...utils import compute_checksum, retrieve_audio_bytes + +APP = Flask(__name__) + + +class JobStatus(Enum): + QUEUED = 0 + FETCHING = 1 + RUNNING = 2 + FINALIZED = 3 + + +class JobError(Exception): + pass + + +class FetchAudioError(JobError): + pass + + +class BulkyAudioError(JobError): + pass + + +_MANAGER = multiprocessing.Manager() +_JOB_QUEUE = _MANAGER.Queue() +_JOB_INPUTS = _MANAGER.dict() +_JOB_STATUS = _MANAGER.dict() +_JOB_OUTPUTS = _MANAGER.dict() + + +def _work(wid): + while True: + print(f"(WID {wid}) Waiting for job") + jid = _JOB_QUEUE.get() + job_def = _JOB_INPUTS[jid] + + print(f"(WID {wid}) Working on {jid}:\n{job_def}") + + def status_change_callback(s): + print(f"(WID {wid}) Status update for {jid}: {s.name}") + assert isinstance(s, JobStatus) or isinstance(s, SheetSageStatus) + _JOB_STATUS[jid] = s + + output = None + stack_trace = None + + # Fetch audio + if isinstance(job_def["audio_path_bytes_or_url"], str): + status_change_callback(JobStatus.FETCHING) + try: + audio_bytes = retrieve_audio_bytes( + job_def["audio_path_bytes_or_url"], + max_filesize_mb=ARGS["fetch_max_filesize_mb"], + max_duration_seconds=ARGS["fetch_max_duration_seconds"], + timeout=ARGS["fetch_timeout_seconds"], + ) + job_def["audio_path_bytes_or_url"] = audio_bytes + except ValueError: + output = BulkyAudioError() + stack_trace = traceback.format_exc() + except Exception: + output = FetchAudioError() + stack_trace = traceback.format_exc() + + # Run + if stack_trace is None: + status_change_callback(JobStatus.RUNNING) + try: + lead_sheet, segment_beats, segment_beats_times = sheetsage( + **job_def, status_change_callback=status_change_callback + ) + output_path = pathlib.Path(ARGS["tmp_dir"], f"{jid}.json") + with open(output_path, "w") as f: + f.write( + json.dumps( + { + "lead_sheet": lead_sheet, + "segment_beats": segment_beats, + "segment_beats_times": segment_beats_times, + } + ) + ) + output = output_path + except Exception as e: + output = JobError() + stack_trace = traceback.format_exc() + + # Finalize + print(f"(WID {wid}) Finalizing {jid}") + assert isinstance(output, pathlib.Path) or isinstance(output, JobError) + _JOB_OUTPUTS[jid] = output + if isinstance(output, pathlib.Path): + status_change_callback(JobStatus.FINALIZED) + else: + assert stack_trace is not None + print(f"(WID {wid}) Exception during {jid}:\n{stack_trace.strip()}") + + +@APP.errorhandler(400) +@APP.errorhandler(500) +def _api_error(e): + return jsonify(e.description), e.code + + +@APP.route("/ping", methods=["GET"]) +def ping(): + return "Pong", 200 + + +@APP.route("/submit", methods=["POST"]) +def submit(): + # Check payload size + if ARGS["max_payload_size_mb"] is not None and request.content_length > ( + ARGS["max_payload_size_mb"] * 1024 * 1024 + ): + abort(413, description="Too large") + + # Define arguments + arg_to_sanitize_fn = { + "audio_url": str, + "audio_file": None, + "segment_start_hint": float, + "segment_end_hint": float, + "legacy_behavior": lambda i: bool(int(i)), + "melody_threshold": float, + "harmony_threshold": float, + } + + # Check arguments + if request.json is not None: + r = dict(request.json) + elif request.form is not None: + r = dict(request.form) + else: + abort(400, description="Unknown request format") + for k in r.keys(): + if k not in arg_to_sanitize_fn: + abort(400, description=f"Unknown argument: {k}") + + # Sanitize arguments + for k, fn in arg_to_sanitize_fn.items(): + if k in r and fn is not None: + try: + r[k] = fn(r[k]) + except: + abort(400, description=f"Bad '{k}'") + + # Create job definition + job_def = { + "audio_path_bytes_or_url": None, + "segment_start_hint": None, + "segment_end_hint": None, + "use_jukebox": ARGS["jukebox"], + "legacy_behavior": False, + "melody_threshold": None, + "harmony_threshold": None, + } + + # Parse audio_url and audio_file + audio_file = request.files.get("audio_file") + if audio_file is not None: + # Audio was uploaded + try: + audio_mimetype = audio_file.content_type + audio_file_bytes = BytesIO() + audio_file.save(audio_file_bytes) + audio_file_bytes.seek(0) + audio_file_bytes = audio_file_bytes.read() + audio_file_checksum = compute_checksum(audio_file_bytes, algorithm="sha256") + except: + abort(400, description="Bad 'audio_file'") + try: + audio_path = pathlib.Path(ARGS["tmp_dir"], "audio", audio_file_checksum) + audio_path.parent.mkdir(parents=True, exist_ok=True) + if not audio_path.is_file(): + with open(audio_path, "wb") as f: + f.write(audio_file_bytes) + except: + abort(500) + job_def["audio_path_bytes_or_url"] = audio_path + elif "audio_url" in r: + # Media needs to be retrieved from URL + try: + audio_url = r["audio_url"].strip() + assert len(audio_url) > 0 + except: + abort(400, description="Bad 'audio_url'") + job_def["audio_path_bytes_or_url"] = audio_url + else: + abort(400, description="No audio specified") + + # Parse float args + for k in [ + "segment_start_hint", + "segment_end_hint", + "legacy_behavior", + "melody_threshold", + "harmony_threshold", + ]: + if k in r: + job_def[k] = r[k] + + # Compute job ID + jid = compute_checksum( + json.dumps(job_def, sort_keys=True, indent=2).encode("utf-8"), + algorithm="sha1", + ) + + # Submit to queue + position = None + status = _JOB_STATUS.get(jid) + output = _JOB_OUTPUTS.get(jid) + actively_processing = output is None and status is not None + already_cached = isinstance(output, pathlib.Path) and output.is_file() + if not (actively_processing or already_cached): + position = _JOB_QUEUE.qsize() + _JOB_INPUTS[jid] = job_def + _JOB_STATUS[jid] = JobStatus.QUEUED + if output is not None: + del _JOB_OUTPUTS[jid] + _JOB_QUEUE.put(jid) + + return {"jid": jid, "cached": already_cached, "position": position} + + +@APP.route("/heartbeat/", methods=["GET"]) +def heartbeat(jid): + status = _JOB_STATUS.get(jid) + if status is None: + abort(404, description="INVALID_ID") + output = _JOB_OUTPUTS.get(jid) + if isinstance(output, BulkyAudioError): + abort(400, description="AUDIO_TOO_LONG_OR_TOO_BIG") + elif isinstance(output, JobError): + abort(500, description=status.name) + return jsonify(status.name) + + +@APP.route("/lead-sheet/", methods=["GET"]) +def download(jid): + if isinstance(jid, str) and jid.endswith(".json"): + jid = jid[:-5] + output = _JOB_OUTPUTS.get(jid) + if output is None: + abort(404, description="INVALID_ID") + if not isinstance(output, pathlib.Path): + abort(500) + return send_file(output, download_name=f"{jid}.json", max_age=7 * 24 * 60 * 60) + + +def __init(): + import os + from argparse import ArgumentParser + + from flask_cors import CORS + + parser = ArgumentParser() + parser.add_argument("--port", type=int) + parser.add_argument("--cors", action="store_true") + parser.add_argument("--cors_allow", type=str) + parser.add_argument("--ssl_crt_path", type=str) + parser.add_argument("--ssl_key_path", type=str) + parser.add_argument("--jukebox", action="store_true") + parser.add_argument("--num_workers", type=int) + parser.add_argument("--max_payload_size_mb", type=int) + parser.add_argument("--fetch_max_filesize_mb", type=int) + parser.add_argument("--fetch_max_duration_seconds", type=float) + parser.add_argument("--fetch_timeout_seconds", type=int) + parser.add_argument("--tmp_dir", type=str) + parser.set_defaults( + port=8000, + cors=False, + cors_allow=None, + ssl_crt_path=None, + ssl_key_path=None, + jukebox=False, + num_workers=1, + max_payload_size_mb=32, + fetch_max_filesize_mb=128, + fetch_max_duration_seconds=660, + fetch_timeout_seconds=60, + tmp_dir="/tmp/sheetsage", + ) + + global ARGS + ARGS = vars(parser.parse_args()) + print(ARGS) + + # Indicate that Jukebox support is forthcoming + if ARGS["jukebox"] and ARGS["num_workers"] > 1: + raise NotImplementedError() + + # Enable CORS + if ARGS["cors"] or ARGS["cors_allow"] is not None: + kwargs = {} + if ARGS["cors_allow"] is not None: + kwargs["origins"] = [o.strip() for o in ARGS["cors_allow"].split(",")] + CORS(APP, **kwargs) + + # Create tmp dir + ARGS["tmp_dir"] = pathlib.Path(ARGS["tmp_dir"]) + ARGS["tmp_dir"].mkdir(parents=True, exist_ok=True) + + # Worker processes + if ARGS["num_workers"] <= 0: + raise ValueError() + processes = [ + multiprocessing.Process(target=_work, args=(wid,)) + for wid in range(ARGS["num_workers"]) + ] + [p.start() for p in processes] + + # Start HTTP server + gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "") + if not gunicorn: + kwargs = { + "debug": True, + "use_reloader": True, + "host": "0.0.0.0", + "port": ARGS["port"], + } + if ARGS["ssl_crt_path"] is not None and ARGS["ssl_key_path"] is not None: + kwargs["ssl_context"] = (ARGS["ssl_crt_path"], ARGS["ssl_key_path"]) + APP.run(**kwargs) + + # Join workers + [p.join() for p in processes] + + +if __name__ == "__main__": + __init() diff --git a/sheetsage/theory/__init__.py b/sheetsage/theory/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..269a5856b6637ff7c4cbf87dc8663b6d1cf91f28 --- /dev/null +++ b/sheetsage/theory/__init__.py @@ -0,0 +1,23 @@ +from .basic import HumanPitchName, LilyPitchName, PitchClass, PitchInterval +from .internal import ( + Chord, + Harmony, + Key, + KeyChanges, + Melody, + Meter, + MeterChanges, + Note, + Tempo, + TempoChanges, +) +from .lead_sheet import LeadSheet +from .theorytab import ( + TheorytabChord, + TheorytabKey, + TheorytabMeter, + TheorytabNote, + TheorytabTempo, + TheorytabValueError, +) +from .utils import estimate_key_changes, theorytab_find_applicable diff --git a/sheetsage/theory/basic.py b/sheetsage/theory/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..106435193d324fe64b8a6c66391224b0409ea425 --- /dev/null +++ b/sheetsage/theory/basic.py @@ -0,0 +1,125 @@ +_HUMAN_PN_TO_PC = { + "C": 0, + "D": 2, + "E": 4, + "F": 5, + "G": 7, + "A": 9, + "B": 11, +} + +_PC_TO_FLAT_HUMAN_PN = "C Db D Eb E F Gb G Ab A Bb B".split() + +_PC_TO_SHARP_HUMAN_PN = "C C# D D# E F F# G G# A A# B".split() + + +class PitchClass(int): + def __new__(cls, pc): + if not isinstance(pc, int): + raise TypeError() + if pc < 0 or pc >= 12: + raise ValueError() + return super().__new__(cls, pc) + + def as_human_pitch_name(self, enharmonics="b"): + if enharmonics == "b": + d = _PC_TO_FLAT_HUMAN_PN + elif enharmonics == "#": + d = _PC_TO_SHARP_HUMAN_PN + else: + raise ValueError() + return HumanPitchName(d[self]) + + def as_lily_pitch_name(self, enharmonics="es"): + if enharmonics == "es": + enharmonics = "b" + elif enharmonics == "is": + enharmonics = "#" + else: + raise ValueError() + return self.as_human_pitch_name(enharmonics=enharmonics).as_lily_pitch_name() + + +class PitchInterval(int): + def __new__(cls, pi): + if not isinstance(pi, int): + raise TypeError() + return super().__new__(cls, pi) + + +class HumanPitchName(str): + def __new__(cls, pn): + if not isinstance(pn, str): + raise TypeError() + if len(pn) == 0: + raise ValueError() + if pn[0] not in _HUMAN_PN_TO_PC: + raise ValueError() + accidentals = list(pn[1:]) + if any(a not in ["b", "#"] for a in accidentals): + raise ValueError() + if len(set(accidentals)) > 1: + raise ValueError() + if len(accidentals) > 2: + raise ValueError() + return super().__new__(cls, pn) + + def as_pitch_class(self): + pc = _HUMAN_PN_TO_PC[self[0]] + accidental = 0 + for c in self[1:]: + if c == "b": + accidental -= 1 + elif c == "#": + accidental += 1 + else: + assert False + return PitchClass((pc + accidental) % 12) + + def as_lily_pitch_name(self): + pn = self[0].lower() + for c in self[1:]: + if c == "b": + pn += "es" + elif c == "#": + pn += "is" + else: + assert False + return LilyPitchName(pn) + + +class LilyPitchName(str): + def __new__(cls, pn): + if not isinstance(pn, str): + raise TypeError() + if len(pn) == 0: + raise ValueError() + if pn.lower() != pn: + raise ValueError() + if pn[0].upper() not in _HUMAN_PN_TO_PC: + raise ValueError() + accidentals = pn[1:] + if len(accidentals) % 2 != 0: + raise ValueError() + accidentals = [accidentals[i : i + 2] for i in range(0, len(accidentals), 2)] + if any(a not in ["es", "is"] for a in accidentals): + raise ValueError() + if len(set(accidentals)) > 1: + raise ValueError() + if len(accidentals) > 3: + raise ValueError() + return super().__new__(cls, pn) + + def as_pitch_class(self): + return self.as_human_pitch_name().as_pitch_class() + + def as_human_pitch_name(self): + pn = self[0].upper() + for i in range(1, len(self), 2): + if self[i : i + 2] == "es": + pn += "b" + elif self[i : i + 2] == "is": + pn += "#" + else: + assert False + return HumanPitchName(pn) diff --git a/sheetsage/theory/internal.py b/sheetsage/theory/internal.py new file mode 100644 index 0000000000000000000000000000000000000000..6631957873de813b948dd521a0719c681afb0502 --- /dev/null +++ b/sheetsage/theory/internal.py @@ -0,0 +1,304 @@ +import numpy as np + +from .basic import PitchClass, PitchInterval + +_LILY_NAME_TO_SCALE_DEGREES = { + "major": (2, 2, 1, 2, 2, 2), + "dorian": (2, 1, 2, 2, 2, 1), + "phrygian": (1, 2, 2, 2, 1, 2), + "lydian": (2, 2, 2, 1, 2, 2), + "mixolydian": (2, 2, 1, 2, 2, 1), + "minor": (2, 1, 2, 2, 1, 2), + "locrian": (1, 2, 2, 1, 2, 2), +} + +_SCALE_DEGREES_TO_LILY_NAME = {v: k for k, v in _LILY_NAME_TO_SCALE_DEGREES.items()} + + +_KEY_TO_ENHARMONICS = {} +for o, ln in zip( + [0, 2, 4, 5, 7, 9, 11], + ["major", "dorian", "phrygian", "lydian", "mixolydian", "minor", "locrian"], +): + for i, pc in enumerate(range(12)): + pc = (o + (pc * 7)) % 12 + ks = (pc, _LILY_NAME_TO_SCALE_DEGREES[ln]) + enharmonics = "#" if i <= 6 else "b" + _KEY_TO_ENHARMONICS[ks] = enharmonics + + +_CHORD_DEGREES_TO_LILY_NAME = { + (4, 3): "", # Major + (3, 4): "m", # Minor + (3, 4, 3): "m7", # Minor 7 + (4, 3, 3): "7", # 7 + (4, 3, 4): "maj7", # Major 7 + (5, 2): "sus4", # Sus 4 + (4, 3, 7): "9^7", # Add 9 + (3, 3): "dim", # Dim + (3, 3, 4): "m7.5-", # Dim minor 7 + (2, 5): "sus2", # Sus 2 + (5, 2, 3): "7sus4", # 7 Sus 4 + (3, 4, 3, 4): "m9", # Minor 9 + (4, 3, 4, 3): "maj9", # Major 9 + (2, 5, 3): "7sus2", # 7 Sus 2 + (3, 4, 7): "m9^7", # Minor Add 9 + (3, 3, 3): "dim7", # Dim 7 + (2, 5, 4): "maj7sus2", # Major 7 Sus 2 + (4, 3, 3, 4): "9", # 9 + (2, 3, 2): "11.9^7", # Sus 2 Sus 4 + (4, 4): "aug", # Aug +} + +_LILY_ABSOLUTE_OCTAVE = 3 + + +class _ImmutableIterable(tuple): + def __new__(cls, *args, **kwargs): + return super().__new__(cls, *args, **kwargs) + + +class Meter(_ImmutableIterable): + # Semantics: https://en.wikipedia.org/wiki/Metre_(music)#Metric_structure + # Meter is defined by "pulse groups": collections of repeating patterns of accented pulses, i.e., measures + # A "pulse group" has a "primary" and "secondary" subdivision + # "Primary subdivision" is synonymous with "pulse" + # Primary subdivision names: "duple" = 2, "triple" = 3, "quadruple" = 4, ... + # Secondary subdivision names: "simple" = 2, "compound" = 3 + # Here we add a tertiary subdivision which refers to the quantization + # Time signatures are abstractions of meter which also take readability into account + # E.g., 3/4 with sixteenth note subdivisions is (3, 2, 2), because we have a simple triple meter w/ each secondary subdivision divided twice + def __new__(cls, primary, secondary, tertiary): + meter = (primary, secondary, tertiary) + if meter not in [(3, 2, 2), (4, 2, 2)]: + raise NotImplementedError() + return super().__new__(cls, meter) + + def as_lily(self): + assert self in [(3, 2, 2), (4, 2, 2)] + if self == (3, 2, 2): + result = ("3", "4") + else: + result = ("4", "4") + return result + + +class Tempo(_ImmutableIterable): + def __new__(cls, pulses_per_minute): + if not isinstance(pulses_per_minute, int): + raise TypeError() + if pulses_per_minute <= 0: + raise ValueError() + return super().__new__(cls, (pulses_per_minute,)) + + def as_lily(self, meter): + if not isinstance(meter, Meter): + raise TypeError() + assert meter in [(3, 2, 2), (4, 2, 2)] + return ("4", str(self[0])) + + +class Key(_ImmutableIterable): + def __new__(cls, root_pc, scale_degree_pis): + if not isinstance(root_pc, int): + raise TypeError() + if not isinstance(scale_degree_pis, tuple): + raise TypeError() + for pi in scale_degree_pis: + if pi <= 0: + raise ValueError() + if sum(scale_degree_pis) >= 12: + raise ValueError() + return super().__new__( + cls, + (PitchClass(root_pc), tuple(PitchInterval(pi) for pi in scale_degree_pis)), + ) + + def as_lily(self): + enharmonics = _KEY_TO_ENHARMONICS.get(self) + if enharmonics is None: + raise ValueError("Unknown scale") + root = self[0].as_human_pitch_name(enharmonics=enharmonics).as_lily_pitch_name() + scale_name = _SCALE_DEGREES_TO_LILY_NAME.get(self[1]) + assert scale_name is not None + return (root, scale_name) + + +class Note(_ImmutableIterable): + def __new__(cls, pc, octave): + if not isinstance(pc, int): + raise TypeError() + if not isinstance(octave, int): + raise TypeError() + return super().__new__(cls, (PitchClass(pc), int(octave))) + + def as_lily(self, key, octave_0=4): + if not isinstance(key, Key): + raise TypeError() + enharmonics = _KEY_TO_ENHARMONICS.get(key) + if enharmonics is None: + raise ValueError() + pitch_class_str = ( + self[0].as_human_pitch_name(enharmonics=enharmonics).as_lily_pitch_name() + ) + octave = (octave_0 - _LILY_ABSOLUTE_OCTAVE) + self[1] + octave_str = ("'" if octave > 0 else ",") * abs(octave) + return (pitch_class_str, octave_str) + + def as_midi_pitch(self, octave_0=4): + return 12 + (12 * (octave_0 + self[1])) + self[0] + + +class Chord(_ImmutableIterable): + def __new__(cls, root_pc, chord_degree_pis): + if root_pc is None: + if chord_degree_pis is not None: + raise ValueError() + t = (None, None) + else: + if not isinstance(root_pc, int): + raise TypeError() + if not isinstance(chord_degree_pis, tuple): + raise TypeError() + for pi in chord_degree_pis: + if pi <= 0: + raise ValueError() + t = ( + PitchClass(root_pc), + tuple(PitchInterval(pi) for pi in chord_degree_pis), + ) + return super().__new__(cls, t) + + def as_lily(self, key): + if not isinstance(key, Key): + raise TypeError() + if self[0] is None: + assert self[1] is None + result = ("r", "") + else: + enharmonics = _KEY_TO_ENHARMONICS.get(key) + if enharmonics is None: + raise ValueError() + root_str = ( + self[0] + .as_human_pitch_name(enharmonics=enharmonics) + .as_lily_pitch_name() + ) + result = (root_str, _CHORD_DEGREES_TO_LILY_NAME.get(self[1], self[1])) + return result + + def as_midi_pitches(self, octave_0=3): + if self[0] is None: + assert self[1] is None + result = [] + else: + chord = [self[0]] + (self[0] + np.cumsum(self[1])).tolist() + result = (12 + (12 * octave_0) + np.array(chord)).tolist() + return result + + +class _InstantEvent(_ImmutableIterable): + def __new__(cls, event_cls, onset, event): + if not isinstance(onset, int): + raise TypeError() + if onset < 0: + raise ValueError() + event = event_cls(*event) + assert isinstance(onset, int) + assert isinstance(event, event_cls) + assert isinstance(event, _ImmutableIterable) + return super().__new__(cls, (onset, event)) + + +class _SustainedEvent(_ImmutableIterable): + def __new__(cls, event_cls, onset, duration, event): + onset, event = _InstantEvent(event_cls, onset, event) + if not isinstance(duration, int): + raise TypeError() + if duration < 0: + raise ValueError() + assert isinstance(onset, int) + assert isinstance(duration, int) + assert isinstance(event, event_cls) + assert isinstance(event, _ImmutableIterable) + return super().__new__(cls, (onset, duration, event)) + + +class _InstantEventList(_ImmutableIterable): + def __new__(cls, event_cls, *args): + # Instantiate and sort + instant_events = [_InstantEvent(event_cls, *ie) for ie in args] + instant_events = sorted(instant_events, key=lambda ie: ie[0]) + + # Check that no two start on same offset + offsets = set(ie[0] for ie in instant_events) + if len(offsets) != len(instant_events): + raise ValueError() + + # Check that all events constitute a change + last_ie = None + for ie in instant_events: + if last_ie is not None and ie[1] == last_ie[1]: + raise ValueError() + last_ie = ie + + return super().__new__(cls, tuple(instant_events)) + + +class _SustainedEventList(_ImmutableIterable): + def __new__(cls, event_cls, *args): + # Instantiate and sort + sustained_events = [_SustainedEvent(event_cls, *se) for se in args] + sustained_events = sorted(sustained_events, key=lambda se: se[0]) + + # Check that no two start on same offset + offsets = set(se[0] for se in sustained_events) + if len(offsets) != len(sustained_events): + raise ValueError() + + # Check that all durations are nonzero + if any(d == 0 for _, d, _ in sustained_events): + raise ValueError() + + # Ensure monophonic + for i, se in enumerate(sustained_events): + if i + 1 < len(sustained_events): + max_duration = sustained_events[i + 1][0] - se[0] + assert max_duration > 0 + if se[1] > max_duration: + raise ValueError() + + return super().__new__(cls, tuple(sustained_events)) + + +class _DefinedAtStartInstantEventList(_InstantEventList): + def __new__(cls, event_cls, *args): + instant_events = super().__new__(cls, event_cls, *args) + if len(instant_events) == 0 or instant_events[0][0] != 0: + raise ValueError() + return instant_events + + +class MeterChanges(_DefinedAtStartInstantEventList): + def __new__(cls, *args): + return super().__new__(cls, Meter, *args) + + +class TempoChanges(_DefinedAtStartInstantEventList): + def __new__(cls, *args): + return super().__new__(cls, Tempo, *args) + + +class KeyChanges(_DefinedAtStartInstantEventList): + def __new__(cls, *args): + return super().__new__(cls, Key, *args) + + +class Harmony(_InstantEventList): + def __new__(cls, *args): + return super().__new__(cls, Chord, *args) + + +class Melody(_SustainedEventList): + def __new__(cls, *args): + return super().__new__(cls, Note, *args) diff --git a/sheetsage/theory/lead_sheet.py b/sheetsage/theory/lead_sheet.py new file mode 100644 index 0000000000000000000000000000000000000000..8a60628ad3448d2e97dae903e1c97144a1e66ea6 --- /dev/null +++ b/sheetsage/theory/lead_sheet.py @@ -0,0 +1,514 @@ +import tempfile +from collections import defaultdict + +import numpy as np +import pretty_midi + +from ..align import create_beat_to_time_fn +from .internal import ( + Harmony, + KeyChanges, + Melody, + MeterChanges, + Note, + TempoChanges, + _ImmutableIterable, +) +from .theorytab import ( + TheorytabChord, + TheorytabKey, + TheorytabMeter, + TheorytabNote, + TheorytabTempo, + TheorytabValueError, +) +from .utils import theorytab_find_applicable + +_LILY_HEADER_TEMPLATE = r""" +\header {{ + {title_line} + {composer_line} +}} +""".strip() + +_LILY_TEMPLATE = r""" +#(set-default-paper-size "letter") + +{header} + +<< + +\new ChordNames {{ + \set majorSevenSymbol = \markup {{ maj7 }} + \set additionalPitchPrefix = #"add" + \chordmode {{ + {harmony} + }} +}} + +\new Staff {{ + {{ + \clef {clef} + \key {key} + \time {meter} + \tempo {tempo} + {melody} + }} +}} + +>> + +\version "2.18.2" +""".strip() + + +_NUM_SIXTEENTHS_TO_LILY_NAME = { + 1: "16", + 3: "8.", + 2: "8", + 4: "4", + 6: "4.", + 8: "2", + 12: "2.", + 16: "1", +} + + +class LeadSheet(_ImmutableIterable): + def __new__( + cls, + meter_changes, + tempo_changes, + key_changes, + harmony, + melody, + total_num_tertiary=None, + ): + # Run value checks + meter_changes = MeterChanges(*meter_changes) + tempo_changes = TempoChanges(*tempo_changes) + key_changes = KeyChanges(*key_changes) + harmony = Harmony(*harmony) + melody = Melody(*melody) + + # Compute tertiary per group (measure) + if len(meter_changes) != 1: + raise NotImplementedError() + meter = meter_changes[0][1] + assert meter in [(3, 2, 2), (4, 2, 2)] + + # TODO: Ensure all changes start on downbeats + + # Compute and/or validate total_num_tertiary + if total_num_tertiary is None: + total_num_tertiary = 1 + user_defined = False + else: + if not isinstance(total_num_tertiary, int): + raise TypeError() + if total_num_tertiary <= 0: + raise ValueError() + user_defined = True + for l in [meter_changes, tempo_changes, key_changes, harmony, melody]: + if len(l) == 0: + continue + if len(l[-1]) == 2: + o, _ = l[-1] + d = 1 + else: + o, d, _ = l[-1] + if (o + d) > total_num_tertiary: + if user_defined: + raise ValueError() + else: + total_num_tertiary = o + d + + # Round up to nearest measure + # NOTE: We always need at least one measure because key/meter are defined at the beginning + tertiary_per_group = int(np.prod(meter)) + while total_num_tertiary % tertiary_per_group != 0: + total_num_tertiary += 1 + assert isinstance(total_num_tertiary, int) + assert total_num_tertiary % tertiary_per_group == 0 + assert total_num_tertiary // tertiary_per_group > 0 + + return super().__new__( + cls, + ( + meter_changes, + tempo_changes, + key_changes, + harmony, + melody, + total_num_tertiary, + ), + ) + + def as_lily( + self, + clef="treble", + adjust_melody_octave=True, + skip_unknown_chords=False, + artist=None, + title=None, + ): + if clef not in ["treble", "bass"]: + raise ValueError() + ( + meter_changes, + tempo_changes, + key_changes, + harmony, + melody, + total_num_tertiary, + ) = self + + # Format meter + assert len(meter_changes) == 1 + meter = meter_changes[0][1] + assert meter in [(3, 2, 2), (4, 2, 2)] + tertiary_per_group = int(np.prod(meter)) + meter_lily = meter.as_lily() + meter_lily = f"{meter_lily[0]}/{meter_lily[1]}" + + # Format tempo + if len(tempo_changes) != 1: + raise NotImplementedError() + assert len(tempo_changes) == 1 + tempo = tempo_changes[0][1] + tempo_lily = tempo.as_lily(meter) + tempo_lily = f"{tempo_lily[0]} = {tempo_lily[1]}" + + # Format key + if len(key_changes) != 1: + raise NotImplementedError() + key = key_changes[0][1] + key_lily = key.as_lily() + key_lily = f"{key_lily[0]} \\{key_lily[1]}" + + # Add in rests in between chords + chords_and_rests = [] + if len(harmony) == 0: + chords_and_rests.append((total_num_tertiary, None)) + else: + for i, (t, c) in enumerate(harmony): + if i == 0 and t > 0: + chords_and_rests.append((t, None)) + if i + 1 < len(harmony): + d = harmony[i + 1][0] - t + else: + d = total_num_tertiary - t + chords_and_rests.append((d, c)) + assert all(d > 0 for d, _ in chords_and_rests) + assert sum(d for d, _ in chords_and_rests) == total_num_tertiary + + # Format chords + harmony = [] + for d, c in chords_and_rests: + # NOTE: c is None means no chord *change*, cs is (None, None) means *change* to N.C. + if c is None: + lpc = ("s", "") + else: + lpc = c.as_lily(key) + if not isinstance(lpc[1], str): + assert isinstance(lpc[1], tuple) + if not skip_unknown_chords: + raise ValueError("Unknown chord") + lpc = ("s", "") + lp = f"{lpc[0]}16*{d}" + if len(lpc[1]) > 0: + lp += ":" + lpc[1] + harmony.append(lp) + harmony_lily = " ".join(harmony) + + # Adjust melody to be centered in clef + # NOTE: Finds the octave where the most melody are on the staff lines + if adjust_melody_octave and len(melody) > 0: + if clef == "treble": + midi_pitch_range = (63, 78) # Eb at bottom of treble clef, F# at top + elif clef == "bass": + midi_pitch_range = (42, 58) # Gb at bottom of bass clef, A# at top + else: + assert False + midi_pitches = np.array([ns.as_midi_pitch() for _, _, ns in melody]) + candidate_octaves = np.arange(-1000, 1000) + midi_pitches_adjusted = (candidate_octaves * 12)[ + :, np.newaxis + ] + midi_pitches[np.newaxis, :] + midi_pitches_onstaff = np.logical_and( + midi_pitches_adjusted >= midi_pitch_range[0], + midi_pitches_adjusted <= midi_pitch_range[1], + ) + best_octave = int( + candidate_octaves[ + np.argmax(midi_pitches_onstaff.astype(np.int64).sum(axis=1)) + ] + ) + melody = [(s, d, Note(ns[0], ns[1] + best_octave)) for s, d, ns in melody] + + # Add in rests in between melody + last_offset = 0 + notes_and_rests = [] + for t, d, ns in melody: + assert t >= last_offset + if t != last_offset: + notes_and_rests.append((t - last_offset, None)) + notes_and_rests.append((d, ns)) + last_offset = t + d + t = total_num_tertiary + assert t >= last_offset + if t != last_offset: + notes_and_rests.append((t - last_offset, None)) + assert all(d > 0 for d, _ in notes_and_rests) + assert sum(d for d, _ in notes_and_rests) == total_num_tertiary + + # Beaming logic + bar_to_notes = defaultdict(list) + t = 0 + for d, ns in notes_and_rests: + tied = False + while d > 0: + bar = t // tertiary_per_group + bar_remaining = ((bar + 1) * tertiary_per_group) - t + consumed = min(d, bar_remaining) + if consumed not in _NUM_SIXTEENTHS_TO_LILY_NAME: + while _NUM_SIXTEENTHS_TO_LILY_NAME.get(consumed, ".").endswith("."): + consumed -= 1 + d -= consumed + t += consumed + if ns is None: + lp = "r" + else: + lp = "".join(ns.as_lily(key)) + lp += _NUM_SIXTEENTHS_TO_LILY_NAME[consumed] + lp += "~" if d > 0 else "" + bar_to_notes[bar].append(lp) + tied = True + + # Format notes + melody_lily = " | ".join([" ".join(notes) for _, notes in bar_to_notes.items()]) + + header = "" + if title is not None or artist is not None: + header = _LILY_HEADER_TEMPLATE.format( + title_line="" if title is None else f'title = "{title}"', + composer_line="" if artist is None else f'composer = "{artist}"', + ) + + return _LILY_TEMPLATE.format( + header=header, + clef=clef, + key=key_lily, + meter=meter_lily, + tempo=tempo_lily, + harmony=harmony_lily, + melody=melody_lily, + ) + + def as_midi(self, pulse_to_time_fn=None, adjust_melody_octave=True): + ( + meter_changes, + tempo_changes, + _, + harmony, + melody, + total_num_tertiary, + ) = self + + # Assumptions + assert len(meter_changes) == 1 + meter = meter_changes[0][1] + assert meter in [(3, 2, 2), (4, 2, 2)] + tertiary_per_group = int(np.prod(meter)) + tertiary_per_pulse = int(np.prod(meter[1:])) + + # Create tertiary_to_time_fn + if pulse_to_time_fn is None: + if len(tempo_changes) != 1: + raise NotImplementedError() + tempo = tempo_changes[0][1] + pps = tempo[0] / 60 + tertiaries = [0, tertiary_per_pulse] + times = [0, 1 / pps] + tertiary_to_time_fn = create_beat_to_time_fn(tertiaries, times) + else: + tertiary_to_time_fn = lambda t: pulse_to_time_fn(t / tertiary_per_pulse) + + # Adjust melody to be mostly in midi octave 5 + if adjust_melody_octave and len(melody) > 0: + midi_pitch_range = (60, 71) + midi_pitches = np.array([ns.as_midi_pitch() for _, _, ns in melody]) + candidate_octaves = np.arange(-1000, 1000) + midi_pitches_adjusted = (candidate_octaves * 12)[ + :, np.newaxis + ] + midi_pitches[np.newaxis, :] + midi_pitches_onstaff = np.logical_and( + midi_pitches_adjusted >= midi_pitch_range[0], + midi_pitches_adjusted <= midi_pitch_range[1], + ) + best_octave = int( + candidate_octaves[ + np.argmax(midi_pitches_onstaff.astype(np.int64).sum(axis=1)) + ] + ) + melody = [(s, d, Note(ns[0], ns[1] + best_octave)) for s, d, ns in melody] + + # Create click + click = pretty_midi.Instrument(program=0, is_drum=True) + for t in range(0, total_num_tertiary, tertiary_per_pulse): + velocity = 75 + pitch = 31 + + # Downbeat + if t % tertiary_per_group == 0: + velocity = 100 + pitch = 37 + + click.notes.append( + pretty_midi.Note( + velocity, + pitch, + tertiary_to_time_fn(t), + tertiary_to_time_fn(t + tertiary_per_pulse), + ) + ) + + # Create harmony + harmony_ins = pretty_midi.Instrument(program=24) # Acoustic Guitar (nylon) + for i, (t, c) in enumerate(harmony): + if i + 1 < len(harmony): + d = harmony[i + 1][0] - t + else: + d = total_num_tertiary - t + for p in c.as_midi_pitches(): + harmony_ins.notes.append( + pretty_midi.Note( + 67, + p, + tertiary_to_time_fn(t), + tertiary_to_time_fn(t + d), + ) + ) + + # Create melody + melody_ins = pretty_midi.Instrument(program=0) + for t, d, ns in melody: + melody_ins.notes.append( + pretty_midi.Note( + 100, + ns.as_midi_pitch(), + tertiary_to_time_fn(t), + tertiary_to_time_fn(t + d), + ) + ) + + # Create MIDI + midi = pretty_midi.PrettyMIDI() + midi.instruments.extend([click, harmony_ins, melody_ins]) + with tempfile.NamedTemporaryFile() as f: + midi.write(f.name) + with open(f.name, "rb") as f: + return f.read() + + @classmethod + def from_theorytab( + cls, + analysis, + ignore_inversion=True, + skip_bad_notes_and_chords=False, + ): + # For theorytab we always subdivide into 1/4 beat + beat_to_tertiary = lambda b: round(b * 4) + end_beat = analysis["endBeat"] - 1 + + # Meters + meter_changes = [] + last_meter = None + for ttm in analysis["meters"]: + ttm = TheorytabMeter(ttm) + meter = ttm.as_meter() + if meter != last_meter: + meter_changes.append((beat_to_tertiary(ttm["beat"] - 1), meter)) + last_meter = meter + + # Tempos + tempo_changes = [] + last_tempo = None + for ttt in analysis["tempos"]: + ttt = TheorytabTempo(ttt) + tempo = ttt.as_tempo() + if tempo != last_tempo: + tempo_changes.append((beat_to_tertiary(ttt["beat"] - 1), tempo)) + last_tempo = tempo + + # Keys + ttk_keys = [] + key_changes = [] + last_key = None + for ttk in analysis["keys"]: + ttk = TheorytabKey(ttk) + ttk_keys.append(ttk) + key = ttk.as_key() + if key != last_key: + key_changes.append((beat_to_tertiary(ttk["beat"] - 1), key)) + last_key = key + + # Chords + harmony = [] + last_chord = None + for ttc in analysis["chords"]: + try: + ttc = TheorytabChord(ttc) + except TheorytabValueError as e: + if not skip_bad_notes_and_chords: + raise e + continue + if ttc.will_sound(): + chord = ttc.as_chord( + theorytab_find_applicable(ttk_keys, ttc), + root_position=ignore_inversion, + ) + if chord != last_chord: + ob = ttc["beat"] - 1 + db = ttc["duration"] + if ob + db > (end_beat + 1e-6): + raise ValueError() + harmony.append((beat_to_tertiary(ob), chord)) + last_chord = chord + + # Notes + melody = [] + for ttn in analysis["notes"]: + try: + ttn = TheorytabNote(ttn) + except TheorytabValueError as e: + if not skip_bad_notes_and_chords: + raise e + continue + if ttn.will_sound(): + ob = ttn["beat"] - 1 + db = ttn["duration"] + if ob + db > (end_beat + 1e-6): + raise ValueError() + melody.append( + ( + beat_to_tertiary(ob), + beat_to_tertiary(db), + ttn.as_note(theorytab_find_applicable(ttk_keys, ttn)), + ) + ) + + # Trim extra changes + total_num_tertiary = beat_to_tertiary(end_beat) + meter_changes = [m for m in meter_changes if m[0] < total_num_tertiary] + tempo_changes = [t for t in tempo_changes if t[0] < total_num_tertiary] + key_changes = [k for k in key_changes if k[0] < total_num_tertiary] + + return cls( + meter_changes, + tempo_changes, + key_changes, + harmony, + melody, + total_num_tertiary=total_num_tertiary, + ) diff --git a/sheetsage/theory/theorytab.py b/sheetsage/theory/theorytab.py new file mode 100644 index 0000000000000000000000000000000000000000..f0590d8763408f48b63432eeabfd96539a2f6658 --- /dev/null +++ b/sheetsage/theory/theorytab.py @@ -0,0 +1,428 @@ +import copy +from collections import OrderedDict + +import numpy as np + +from .basic import HumanPitchName +from .internal import Chord, Key, Meter, Note, Tempo + +_THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS = { + "major": (2, 2, 1, 2, 2, 2), + "dorian": (2, 1, 2, 2, 2, 1), + "phrygian": (1, 2, 2, 2, 1, 2), + "lydian": (2, 2, 2, 1, 2, 2), + "mixolydian": (2, 2, 1, 2, 2, 1), + "minor": (2, 1, 2, 2, 1, 2), + "locrian": (1, 2, 2, 1, 2, 2), + "harmonicMinor": (2, 1, 2, 2, 1, 3), + "phrygianDominant": (1, 3, 1, 2, 1, 2), +} + +_THEORYTAB_ACCIDENTAL_STR_TO_NUM_SEMITONES = {"bb": -2, "b": -1, "": 0, "#": 1, "##": 2} +_THEORYTAB_ACCIDENTAL_STR_TO_NUM_SEMITONES_LEGACY_BUG = { + "bb": -1, + "b": -1, + "": 0, + "#": 1, + "##": 1, +} + +# NOTE: Rules written down manually from Hookpad +_THEORYTAB_CHORD_TYPE_TO_ALLOWED_OPTIONS = { + 5: { + "inversions": [0, 1, 2], + "suspensions": [2, 4], + "adds": [9, 4, 6], + "omits": [3, 5], + "alterations": ["b5", "#5"], + }, + 7: { + "inversions": [0, 1, 2, 3], + "suspensions": [2, 4], + "adds": [4, 6], + "omits": [3, 5], + "alterations": ["b5", "#5", "b9", "#9", "#11", "b13"], + }, + 9: { + "inversions": [0], + "suspensions": [4], + "adds": [6], + "omits": [3, 5], + "alterations": ["b5", "#5", "#11", "b13"], + }, + 11: { + "inversions": [0], + "suspensions": [2], + "adds": [], + "omits": [3, 5], + "alterations": ["b5", "#5", "b9", "#9", "b13"], + }, + 13: { + "inversions": [0], + "suspensions": [], + "adds": [], + "omits": [3, 5], + "alterations": ["b5", "#5", "b9", "#9", "#11"], + }, +} + + +class _TheorytabDict(dict): + _FIELDS = [] + + def _check_values(self): + if "beat" in self: + min_beat = 0 if "isRest" in self and self["isRest"] else 1 + if self["beat"] < min_beat: + raise TheorytabValueError("beat") + + def __init__(self, *args, _skip_value_checks=False, **kwargs): + super().__init__(*args, **kwargs) + for f in self._FIELDS: + if f not in self: + raise TheorytabValueError(f"Missing field '{f}'") + for f in self.keys(): + if f not in self._FIELDS: + raise TheorytabValueError(f"Unknown field '{f}'") + if not _skip_value_checks: + self._check_values() + + +class TheorytabValueError(ValueError): + pass + + +class TheorytabMeter(_TheorytabDict): + _FIELDS = ["beat", "numBeats", "beatUnit"] + + def _check_values(self): + super()._check_values() + if self["numBeats"] not in [2, 3, 4, 5, 6, 9, 12]: + raise TheorytabValueError("numBeats") + if self["beatUnit"] not in [1, 3]: + raise TheorytabValueError("beatUnit") + if self["beatUnit"] == 3 and self["numBeats"] not in [3, 6, 9, 12]: + raise TheorytabValueError("numBeats,beatUnit") + + def as_meter(self): + assert self["numBeats"] % self["beatUnit"] == 0 + return Meter( + self["numBeats"] // self["beatUnit"], + 3 if self["beatUnit"] == 3 else 2, + 4 if self["beatUnit"] == 3 else 2, + ) + + +class TheorytabTempo(_TheorytabDict): + _FIELDS = ["beat", "bpm", "swingFactor", "swingBeat"] + + def _check_values(self): + super()._check_values() + if self["bpm"] is None or self["bpm"] < 30 or self["bpm"] > 300: + raise TheorytabValueError("bpm") + if isinstance(self["swingFactor"], int): + if self["swingFactor"] != 0: + raise TheorytabValueError("swingFactor") + else: + if self["swingFactor"] < 0.5 or self["swingFactor"] > 0.75: + raise TheorytabValueError("swingFactor") + if self["swingBeat"] not in [0.5, 0.25]: + raise TheorytabValueError("swingBeat") + + def as_tempo(self): + return Tempo(round(self["bpm"])) + + +class TheorytabKey(_TheorytabDict): + _FIELDS = ["beat", "scale", "tonic"] + + def _check_values(self): + super()._check_values() + if self["scale"] not in _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS: + raise TheorytabValueError("scale") + try: + HumanPitchName(self["tonic"]) + except ValueError: + raise TheorytabValueError("tonic") + + def as_key(self): + return Key( + HumanPitchName(self["tonic"]).as_pitch_class(), + _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS[self["scale"]], + ) + + +class _TheorytabNoteOrChord(_TheorytabDict): + def _check_values(self, eps=1e-8): + super()._check_values() + assert "isRest" in self + assert "duration" in self + min_duration = None if self["isRest"] else eps + if min_duration is not None and self["duration"] < min_duration: + raise TheorytabValueError("duration") + + def will_sound(self, min_duration=1e-8): + return ( + self["beat"] >= 1 and self["duration"] > min_duration and not self["isRest"] + ) + + +class TheorytabNote(_TheorytabNoteOrChord): + _FIELDS = ["sd", "octave", "beat", "duration", "isRest", "recordingEndBeat"] + + def _check_values(self): + super()._check_values() + sd = self["sd"] + if len(sd) not in [1, 2, 3]: + raise TheorytabValueError("sd") + accidental_str = sd[:-1] + if accidental_str not in _THEORYTAB_ACCIDENTAL_STR_TO_NUM_SEMITONES: + raise TheorytabValueError("sd") + sd = int(sd[-1]) - 1 + if sd < 0 or sd >= 7: + raise TheorytabValueError("sd") + if abs(self["octave"]) > 4: + raise TheorytabValueError("octave") + + def as_note(self, key, legacy_behavior=False): + if isinstance(key, dict) and not isinstance(key, TheorytabKey): + key = TheorytabKey(key) + if isinstance(key, TheorytabKey): + key = key.as_key() + if not isinstance(key, Key): + raise TypeError() + result = None + if self.will_sound(**({"min_duration": 0} if legacy_behavior else {})): + key_tonic_pc, key_scale_intervals = key + sd = self["sd"] + accidental_str = sd[:-1] + if legacy_behavior: + accidental = _THEORYTAB_ACCIDENTAL_STR_TO_NUM_SEMITONES_LEGACY_BUG[ + accidental_str + ] + else: + accidental = _THEORYTAB_ACCIDENTAL_STR_TO_NUM_SEMITONES[accidental_str] + sd = int(sd[-1]) - 1 + pitch = 12 * self["octave"] + pitch += key_tonic_pc + pitch += sum(key_scale_intervals[:sd]) + pitch += accidental + result = Note(pitch % 12, pitch // 12) + return result + + +class TheorytabChord(_TheorytabNoteOrChord): + _FIELDS = [ + "root", + "beat", + "duration", + "type", + "inversion", + "applied", + "adds", + "omits", + "alterations", + "suspensions", + "pedal", + "alternate", + "borrowed", + "isRest", + "recordingEndBeat", + ] + + def _check_values(self): + super()._check_values() + + # Check 'root' + if self["root"] <= 0: + if self.will_sound(): + raise TheorytabValueError("root") + else: + if self["root"] not in [1, 2, 3, 4, 5, 6, 7]: + raise TheorytabValueError("root") + + # Check 'type' + if self["type"] not in [5, 7, 9, 11, 13]: + raise TheorytabValueError("type") + + # Check 'inversion' + if self["inversion"] not in [0, 1, 2, 3]: + raise TheorytabValueError("inversion") + + # Check 'applied' + if self["applied"] not in [0, 1, 2, 3, 4, 5, 6, 7]: + raise TheorytabValueError("applied") + + # Check 'adds' + if any(a not in [9, 4, 6] for a in self["adds"]): + raise TheorytabValueError("adds") + if len(self["adds"]) != len(set(self["adds"])): + raise TheorytabValueError("adds") + + # Check 'omits' + if any(o not in [3, 5] for o in self["omits"]): + raise TheorytabValueError("omits") + if len(self["omits"]) != len(set(self["omits"])): + raise TheorytabValueError("omits") + + # Check 'alterations' + if any( + a not in ["b5", "#5", "b9", "#9", "#11", "b13"] for a in self["alterations"] + ): + raise TheorytabValueError("alterations") + if len(self["alterations"]) != len(set(self["alterations"])): + raise TheorytabValueError("alterations") + + # Check 'suspensions' + if any(s not in [2, 4] for s in self["suspensions"]): + raise TheorytabValueError("suspensions") + if len(self["suspensions"]) != len(set(self["suspensions"])): + raise TheorytabValueError("suspensions") + + # Check 'pedal' + if self["pedal"] is not None: + raise TheorytabValueError("pedal") + + # Check 'alternate' + if self["alternate"] != "": + raise TheorytabValueError("alternate") + + # Check 'borrowed' + if not ( + self["borrowed"] == "" + or self["borrowed"] is None + or (isinstance(self["borrowed"], list) and len(self["borrowed"]) == 7) + or self["borrowed"] in _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS + ): + raise TheorytabValueError("borrowed") + + # Check 'type' against others + for name, allowed_options in _THEORYTAB_CHORD_TYPE_TO_ALLOWED_OPTIONS[ + self["type"] + ].items(): + if name == "inversions": + if self["inversion"] not in allowed_options: + raise TheorytabValueError("type,inversion") + else: + if any(o not in allowed_options for o in self[name]): + raise TheorytabValueError(f"type,{name}") + + # Check 'inversion,omits' + if self["inversion"] == 1 and 3 in self["omits"]: + raise TheorytabValueError("inversion,omits") + if self["inversion"] == 2 and 5 in self["omits"]: + raise TheorytabValueError("inversion,omits") + + # Check 'adds,alterations' + for alt in self["alterations"]: + if int(alt[-1]) in self["adds"]: + raise TheorytabValueError("adds,alterations") + + # Check 'adds,suspensions' + if 2 in self["suspensions"] and 9 in self["adds"]: + raise TheorytabValueError("adds,suspensions") + if 4 in self["suspensions"] and 4 in self["adds"]: + raise TheorytabValueError("adds,suspensions") + + # Check 'omits,alterations' + if 5 in self["omits"] and ( + "b5" in self["alterations"] or "#5" in self["alterations"] + ): + raise TheorytabValueError("omits,alterations") + + # Check 'omits,suspensions' + if 3 in self["omits"] and len(self["suspensions"]) > 0: + raise TheorytabValueError("omits,suspensions") + + def as_chord(self, key, root_position=False): + if isinstance(key, dict) and not isinstance(key, TheorytabKey): + key = TheorytabKey(key) + if isinstance(key, TheorytabKey): + key = key.as_key() + if not isinstance(key, Key): + raise TypeError() + result = None + if self.will_sound(): + chord = copy.deepcopy(self) + + # Unsupported + # TODO: + if not root_position and chord["inversion"] != 0: + raise NotImplementedError("inversion") + + # Build chord scale degrees + chord_degrees = set(range(1, chord["type"] + 1, 2)) + + # Apply suspensions + for i, d in enumerate(chord["suspensions"]): + if i == 0: + assert 3 in chord_degrees + chord_degrees.remove(3) + assert d not in chord_degrees + chord_degrees.add(d) + + # Apply adds + for d in chord["adds"]: + if d in [4, 6]: + d += 7 + chord_degrees.add(d) + + # Apply omits + for d in chord["omits"]: + assert d in [3, 5] + assert d in chord_degrees + chord_degrees.remove(d) + + # Apply alterations + for d in chord["alterations"]: + d = int(d[1:]) + chord_degrees.add(d) + + # Convert to list + chord_degrees = sorted(list(chord_degrees)) + + # Find scale intervals + key_tonic_pc, key_scale_intervals = key + + # Apply borrow (changes intervals) + if isinstance(chord["borrowed"], list): + key_scale_intervals = chord["borrowed"] + else: + if chord["borrowed"] in _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS: + key_scale_intervals = _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS[ + chord["borrowed"] + ] + key_scale_intervals = [0] + np.cumsum(key_scale_intervals).tolist() + assert len(key_scale_intervals) == 7 + + # Apply secondary (changes tonic and intervals) + major_scale_intervals = _THEORYTAB_SCALE_NAME_TO_PITCH_INTERVALS["major"] + major_scale_intervals = [0] + np.cumsum(major_scale_intervals).tolist() + if chord["applied"] > 0: + key_tonic_pc = ( + key_tonic_pc + key_scale_intervals[chord["root"] - 1] + ) % 12 + chord["root"] = chord["applied"] + key_scale_intervals = major_scale_intervals + + # Convert scale degrees to pitch offsets + chord_degree_to_interval = OrderedDict() + for d in chord_degrees: + d_abs = (chord["root"] - 1) + (d - 1) + interval = key_scale_intervals[d_abs % 7] + interval += 12 * (d_abs // 7) + chord_degree_to_interval[d] = interval + # NOTE: Not sure if this is a bug in Hookpad or what? + if d == 7 and chord["applied"] == 7: + chord_degree_to_interval[d] -= 1 + + # Apply alterations + for alt in chord["alterations"]: + d = int(alt[1:]) + assert d in chord_degree_to_interval + chord_degree_to_interval[d] += -1 if alt[0] == "b" else 1 + + # Create final chord + result = [key_tonic_pc + v for _, v in chord_degree_to_interval.items()] + result = Chord(result[0] % 12, tuple(np.diff(result).tolist())) + return result diff --git a/sheetsage/theory/utils.py b/sheetsage/theory/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..0fa654b60a93eb6eb9e817bb94894c0a966fea25 --- /dev/null +++ b/sheetsage/theory/utils.py @@ -0,0 +1,117 @@ +import tempfile +from collections import Counter + +from ..utils import run_cmd_sync +from .basic import HumanPitchName +from .internal import Harmony, Key, KeyChanges, Melody, MeterChanges + + +def theorytab_find_applicable(timed_events, search_event, eps=1e-3): + candidates = [t for t in timed_events if (search_event["beat"] - t["beat"]) > -eps] + if len(candidates) == 0: + raise ValueError() + return candidates[-1] + + +def estimate_key_changes(meter_changes, harmony, melody): + meter_changes = MeterChanges(*meter_changes) + harmony = Harmony(*harmony) + melody = Melody(*melody) + + # Compute total num tertiary + meter = meter_changes[0][1] + assert meter in [(3, 2, 2), (4, 2, 2)] + tertiary_per_pulse = meter[1] * meter[2] + tertiary_per_group = meter[0] * tertiary_per_pulse + total_num_tertiary = 0 if len(harmony) == 0 else harmony[-1][0] + 1 + total_num_tertiary = max( + total_num_tertiary, 0 if len(melody) == 0 else sum(melody[-1][:2]) + ) + while total_num_tertiary % tertiary_per_group != 0: + total_num_tertiary += 1 + + # Fake tempo + ppm = 120 + tertiary_to_ms = lambda t: round((t / tertiary_per_pulse) / (ppm / 60) * 1000) + + # "Beat" events + lines = [] + for t in range(0, total_num_tertiary + tertiary_per_pulse, tertiary_per_pulse): + strength = 1 + if t % tertiary_per_group == 0: + strength = 4 + elif meter == (4, 2, 2) and t % (tertiary_per_pulse * 2) == 0: + strength = 2 + lines.append(("Beat", tertiary_to_ms(t), strength)) + + # "Chord" events + pc_to_melisma_pc = {pc: (2 + (7 * pc)) % 12 for pc in range(12)} + for i, (t, c) in enumerate(harmony): + if i == 0: + t = 0 + if i + 1 < len(harmony): + d = harmony[i + 1][0] - t + else: + d = total_num_tertiary - t + lines.append( + ("Chord", tertiary_to_ms(t), tertiary_to_ms(t + d), pc_to_melisma_pc[c[0]]) + ) + + # "Note" events + for t, d, n in melody: + lines.append( + ("Note", tertiary_to_ms(t), tertiary_to_ms(t + d), n.as_midi_pitch()) + ) + + parameters = """ +verbosity=1 +default_profile_value = 1.5 +npc_or_tpc_profile=0 +scoring_mode = 1 +segment_beat_level=3 +beat_printout_level=2 +romnums=0 +romnum_type=0 +running=0 + +%CBMS MODEL +major_profile = 5.0 2.0 3.5 2.0 4.5 4.0 2.0 4.5 2.0 3.5 1.5 4.0 +minor_profile = 5.0 2.0 3.5 4.5 2.0 4.0 2.0 4.5 3.5 2.0 1.5 4.0 +change_penalty=12 + +%K-S MODEL +%major_profile = 6.35 2.23 3.48 2.33 4.38 4.09 2.52 5.19 2.39 3.66 2.29 2.88 +%minor_profile = 6.33 2.68 3.52 5.38 2.60 3.53 2.54 4.75 3.98 2.69 3.34 3.17 +%change_penalty = 2.3 + +%BAYESIAN MODEL +%major_profile = 0.748 0.060 0.488 0.082 0.670 0.460 0.096 0.715 0.104 0.366 0.057 0.400 +%minor_profile = 0.712 0.084 0.474 0.618 0.049 0.460 0.105 0.747 0.404 0.067 0.133 0.330 +%change_penalty = 0.002 + """.strip() + + formatted = "\n".join(["\t".join([str(a) for a in l]) for l in lines]) + with tempfile.NamedTemporaryFile() as f, tempfile.NamedTemporaryFile() as p: + with open(f.name, "w") as f: + f.write(formatted) + with open(p.name, "w") as p: + p.write(parameters) + res, stdout, stderr = run_cmd_sync( + f"melisma-key -p {p.name} {f.name}", timeout=60 + ) + if res != 0 or len(stderr) > 0: + raise Exception(f"{stdout}\n{stderr}".strip()) + + key_to_count = Counter() + for key in stdout.split(): + if key.endswith("m"): + scale = (2, 1, 2, 2, 1, 2) + key = key[:-1] + else: + scale = (2, 2, 1, 2, 2, 2) + key = Key(HumanPitchName(key).as_pitch_class(), scale) + key_to_count[key] += 1 + if len(key_to_count) == 0: + raise Exception("Failed to estimate key") + key = sorted(key_to_count.keys(), key=lambda k: key_to_count[k])[-1] + return KeyChanges((0, key)) diff --git a/sheetsage/utils.py b/sheetsage/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..6d928b2d1fe761cda043b12d1d3fdc8386f6f003 --- /dev/null +++ b/sheetsage/utils.py @@ -0,0 +1,457 @@ +import gzip +import hashlib +import json +import pathlib +import shlex +import subprocess +import tempfile +import warnings +from functools import lru_cache +from io import BytesIO + +import audioread +import librosa +import numpy as np +from PIL import Image +from scipy.io.wavfile import write as wavwrite + + +def compute_checksum(path_or_bytes, algorithm="sha256", gunzip=False, chunk_size=4096): + """Computes checksum of target path. + + Parameters + ---------- + path_or_bytes : :class:`pathlib.Path` or bytes + Location or bytes of file to compute checksum for. + algorithm : str, optional + Hash algorithm (from :func:`hashlib.algorithms_available`); default ``sha256``. + gunzip : bool, optional + If true, decompress before computing checksum. + chunk_size : int, optional + Chunk size for iterating through file. + + Raises + ------ + :class:`FileNotFoundError` + Unknown path. + :class:`IsADirectoryError` + Path is a directory. + :class:`ValueError` + Unknown algorithm. + + Returns + ------- + str + Hex representation of checksum. + """ + if algorithm not in hashlib.algorithms_guaranteed or algorithm.startswith("shake"): + raise ValueError("Unknown algorithm") + computed = hashlib.new(algorithm) + if isinstance(path_or_bytes, bytes): + computed.update(path_or_bytes) + else: + open_fn = gzip.open if gunzip else open + with open_fn(path_or_bytes, "rb") as f: + while True: + data = f.read(chunk_size) + if not data: + break + computed.update(data) + return computed.hexdigest() + + +def run_cmd_sync(cmd, cwd=None, interactive=False, timeout=None): + """Runs a console command synchronously and returns the results. + + Parameters + ---------- + cmd : str + The command to execute. + cwd : :class:`pathlib.Path`, optional + The working directory in which to execute the command. + interactive : bool, optional + If set, run command interactively and pipe all output to console. + timeout : float, optional + If specified, kills process and throws error after this many seconds. + + Returns + ------- + int + Process exit status code. + str, optional + Standard output (if not in interactive mode). + str, optional + Standard error (if not in interactive mode). + + Raises + ------ + :class:`FileNotFoundError` + Unknown command. + :class:`NotADirectoryError` + Specified working directory is not a directory. + :class:`subprocess.TimeoutExpired` + Specified timeout expired. + """ + if cmd is None or len(cmd.strip()) == 0: + raise FileNotFoundError() + + kwargs = {} + if not interactive: + kwargs["stdout"] = subprocess.PIPE + kwargs["stderr"] = subprocess.PIPE + + err = None + with subprocess.Popen(shlex.split(cmd), cwd=cwd, **kwargs) as p: + try: + p_res = p.communicate(timeout=timeout) + except subprocess.TimeoutExpired as e: + err = e + p.kill() + + if err is not None: + raise err + + result = p.returncode + + if not interactive: + stdout, stderr = [s.decode("utf-8").strip() for s in p_res] + result = (result, stdout, stderr) + + return result + + +_RETRIEVE_AUDIO_CMD_TEMPLATE = """ +yt-dlp \ + --no-cache-dir \ + --no-continue \ + --no-playlist \ + --format bestaudio/best \ + {other} \ + {url} +""" + + +@lru_cache(maxsize=1) +def retrieve_audio_bytes( + url, + return_name=False, + max_filesize_mb=None, + max_duration_seconds=None, + timeout=60.0, +): + """Retrieves encoded audio (as raw bytes) from specified URL. + + Parameters + ---------- + url: str + The URL to retrieve from. + return_name: bool + If True, return the retrieved file name. + timeout : float + Max amount of time to wait before throwing an error. + + Returns + ------- + bytes + The raw bytes of the encoded audio file. + str, optional + The name of the encoded audio file, if return_name is True. + + Raises + ------ + :class:`subprocess.TimeoutExpired` + Specified timeout expired. + ValueError + Video too large or too long. + Exception + Error during retrieval. + """ + with tempfile.TemporaryDirectory() as d: + if max_duration_seconds is not None: + status, stdout, stderr = run_cmd_sync( + cmd=_RETRIEVE_AUDIO_CMD_TEMPLATE.format( + url=url.strip(), other="--dump-json" + ), + cwd=d, + timeout=timeout, + ) + try: + assert status == 0 + metadata = json.loads(stdout) + duration = float(metadata["duration"]) + except: + raise Exception(f"Failed to retrieve duration from {url}:\n{stderr}") + if duration > max_duration_seconds: + raise ValueError( + f"Specified url is too long ({duration} > {max_duration_seconds})." + ) + + assert len(list(pathlib.Path(d).iterdir())) == 0 + status, stdout, stderr = run_cmd_sync( + cmd=_RETRIEVE_AUDIO_CMD_TEMPLATE.format( + url=url.strip(), + other="" + if max_filesize_mb is None + else f"--max-filesize {max_filesize_mb}m", + ), + cwd=d, + timeout=timeout, + ) + if max_filesize_mb is not None and "File is larger than max" in stdout: + raise ValueError("Specified url is too large.") + paths = list(pathlib.Path(d).iterdir()) + if status != 0 or len(paths) == 0: + raise Exception(f"Failed to retrieve from {url}:\n{stderr}\n{stdout}") + assert len(paths) == 1 + path = paths[0] + with open(path, "rb") as f: + audio_bytes = f.read() + if return_name: + result = (audio_bytes, path.name) + else: + result = audio_bytes + return result + + +def decode_audio( + path_or_bytes, + sr=None, + offset=0.0, + duration=None, + mono=False, + normalize=False, + res_type="kaiser_best", +): + """Decodes encoded audio from path or raw bytes. + + Parameters + ---------- + path_or_bytes: :class:`pathlib.Path`, str, or bytes + The filepath or raw bytes to decode. + sr: int + If specified, resample audio to this sample rate. + offset: float + Decode audio starting from this timestamp in seconds. + duration: float + Decode at most this many audio in seconds. + mono: bool + If True, average multichannel audio to mono. + normalize: bool + If True, normalize audio to max(abs(audio)) == 1.0. + res_type: str + The resampling algorithm to use (see `librosa.load` documentation). + + Returns + ------- + int + The sample rate of the decoded audio. + :class:`np.ndarray` + A NumPy array of the audio (shape [nsamps, nch], dtype float32). + + Raises + ------ + :class:`FileNotFoundError` + Unknown file. + :class:`RuntimeError` + Unknown file format. + """ + with tempfile.NamedTemporaryFile("wb") as f: + # NOTE: This could be BytesIO but librosa has buggy support. + if isinstance(path_or_bytes, bytes): + f.write(path_or_bytes) + f.flush() + path = f.name + else: + path = path_or_bytes + + # Decode audio file + try: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + audio, sr = librosa.load( + path, + sr=sr, + mono=mono, + offset=offset, + duration=duration, + res_type=res_type, + ) + except audioread.exceptions.NoBackendError as e: + raise RuntimeError("Unknown audio format") from e + + # Check output and rearrange to [nsamps, nch] + assert isinstance(sr, int) + assert audio.dtype == np.float32 + assert audio.ndim in [1, 2] + if audio.ndim == 1: + audio = audio[np.newaxis, :] + assert audio.shape[0] > 0 + audio = np.swapaxes(audio, 0, 1) + audio = np.asfortranarray(audio) + + # Normalize + if normalize and audio.shape[0] > 0: + norm_factor = np.abs(audio).max() + if norm_factor > 0: + audio /= norm_factor + + return sr, audio + + +def encode_audio(path, sr, audio, bitexact=False, timeout=60.0): + """Encodes raw audio array into different file formats using FFmpeg. + + Parameters + ---------- + path: :class:`pathlib.Path`, str + Destination filepath (where the extension determines the codec). + sr: int + The sample rate of the audio. + audio: :class:`np.ndarray` + A NumPy array of the audio (shape [nsamps, nch], dtype float32). + bitexact: bool + If True, ensure reproducible checksums of output file (only on FFmpeg 4+). + timeout: float + Maximum amount of time to wait for encoding. + + Raises + :class:`subprocess.TimeoutExpired` + Specified timeout expired. + :class:`Exception` + FFmpeg threw an error while encoding. + """ + with tempfile.NamedTemporaryFile(suffix=".wav") as f: + wavwrite(f.name, sr, audio) + cmd = f"ffmpeg -v error -i {f.name} -y {'-bitexact' if bitexact else ''} {path}" + status, stdout, stderr = run_cmd_sync(cmd, timeout=timeout) + if status != 0: + raise Exception(f"FFmpeg failed: {stderr}") + assert pathlib.Path(path).is_file() + + +def get_approximate_audio_length(path, timeout=10): + """Retrieves the approximate length of an audio file.""" + status, stdout, stderr = run_cmd_sync( + f"ffprobe -v error -i {path} -show_format -show_streams -print_format json", + timeout=timeout, + ) + try: + assert status == 0 + assert len(stderr) == 0 + except: + raise Exception(f"FFmpeg failed: {stderr}") + d = json.loads(stdout) + duration = float(d["format"]["duration"]) + return duration + + +_LILYPOND_ENGRAVE_TEMPLATE = """ +lilypond \ + -s \ + {args} \ + --{out_format} \ + -o {out_path} \ + {in_path} +""".strip() + + +def engrave( + lilypond, + out_format="png", + transparent=True, + trim=True, + hide_footer=True, + args=None, + timeout=60, +): + if out_format not in ["png", "pdf"]: + raise ValueError() + if args is not None and not isinstance(args, str): + raise ValueError() + + # Adjust lilypond + if hide_footer: + lilypond += "\n\\header { tagline = ##f }" + + # Engrave + with tempfile.TemporaryDirectory() as d: + # Create cmd + in_path = pathlib.Path(d, "in.ly") + with open(in_path, "w") as f: + f.write(lilypond) + args = "" if args is None else args + if out_format != "pdf": + args += " -dpixmap-format=pngalpha" + cmd = _LILYPOND_ENGRAVE_TEMPLATE.format( + args=args, + out_format=out_format, + out_path=pathlib.Path(d, "out"), + in_path=in_path, + ) + + # Run cmd + status, stdout, stderr = run_cmd_sync(cmd, timeout=timeout) + if status != 0: + raise Exception(f"Failed to engrave ({status}): {stderr}") + + # Load output pages + out_paths = sorted( + [p for p in pathlib.Path(d).glob(f"out*.{out_format}") if p.is_file()] + ) + if len(out_paths) == 0: + raise Exception("No output") + assert len(out_paths) == 1 or out_format == "png" + pages = [] + for p in out_paths: + with open(p, "rb") as f: + pages.append(f.read()) + + # Post processes + if out_format == "pdf": + assert len(out_paths) == 1 + result_bytes = pages[0] + else: + + def _png_to_image(png_bytes): + return Image.open(BytesIO(png_bytes)) + + def _image_to_png(im): + bio = BytesIO() + im.save(bio, format="png") + return bio.getvalue() + + def _concatenate(pages_bytes): + pages = [_png_to_image(p) for p in pages_bytes] + cat_width = max([p.width for p in pages]) + cat_height = sum([p.height for p in pages]) + cat = Image.new("RGB", (cat_width, cat_height)) + h = 0 + for p in pages: + cat.paste(p, (0, h)) + h += p.height + return _image_to_png(cat) + + def _trim(page_bytes): + im = _png_to_image(page_bytes) + bbox = im.getbbox() + if bbox is not None: + im = im.crop(bbox) + return _image_to_png(im) + + def _remove_transparency(page_bytes): + im = _png_to_image(page_bytes).convert("RGBA") + background = Image.new("RGBA", im.size, (255, 255, 255)) + im = Image.alpha_composite(background, im) + return _image_to_png(im) + + if len(pages) == 1: + result_bytes = pages[0] + else: + result_bytes = _concatenate(pages) + + if trim: + result_bytes = _trim(result_bytes) + if not transparent: + result_bytes = _remove_transparency(result_bytes) + + return result_bytes diff --git a/sheetsage/weights/0919_00_e0830_oafmelspecnorm/7d82e6839e582936ea428a823a0d868075a52dc5.cfg.json b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/7d82e6839e582936ea428a823a0d868075a52dc5.cfg.json new file mode 100644 index 0000000000000000000000000000000000000000..c25ea3dcdc2b94ee37b43f091f956ca4707ff4e6 --- /dev/null +++ b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/7d82e6839e582936ea428a823a0d868075a52dc5.cfg.json @@ -0,0 +1,19 @@ +{ + "batch_size": 64, + "dataset": "0831_theorytab_beatframebased_jukebox_pitches", + "eval_frequency": 32, + "hacks": [ + "pos_emb", + "4layers", + "octave_invariant_loss", + "pitch_class_loss" + ], + "lr": 0.0001, + "max_num_steps": null, + "model": "transformer", + "seed": 0, + "src": "0829_oafmelspecnorm_mean_beat", + "src_max_len": 384, + "summarize_frequency": 32, + "tgt_max_len": 384 +} \ No newline at end of file diff --git a/sheetsage/weights/0919_00_e0830_oafmelspecnorm/model.pt b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/model.pt new file mode 100644 index 0000000000000000000000000000000000000000..fb65306e6a6953289c2921c4e1f5292a62440407 --- /dev/null +++ b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/model.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70f10a4146da8f1294597516622901d93621c5cd1bbb4e9dc831f9c43c081ef4 +size 59496040 diff --git a/sheetsage/weights/0919_00_e0830_oafmelspecnorm/step.pkl b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/step.pkl new file mode 100644 index 0000000000000000000000000000000000000000..173ea6669c7b19ba2e2a8582d0a51b028092cc62 --- /dev/null +++ b/sheetsage/weights/0919_00_e0830_oafmelspecnorm/step.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:287bdfc444a79ebee76722726d29f57169d2170c95363ed122866ea534206006 +size 6 diff --git a/sheetsage/weights/0919_02_e0908_oafmelspecnorm/5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4.cfg.json b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4.cfg.json new file mode 100644 index 0000000000000000000000000000000000000000..fc017b46f6f0f97ddca57bec6ec3fa5149789689 --- /dev/null +++ b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/5b739ce5efa2b6d4d70c5f1feac802684f0ee6f4.cfg.json @@ -0,0 +1,19 @@ +{ + "batch_size": 64, + "dataset": "0908_theorytab_beatframebased_jukebox_chords", + "eval_frequency": 32, + "hacks": [ + "pos_emb", + "4layers", + "octave_invariant_loss", + "pitch_class_loss" + ], + "lr": 0.0001, + "max_num_steps": null, + "model": "transformer", + "seed": 0, + "src": "0829_oafmelspecnorm_mean_beat", + "src_max_len": 384, + "summarize_frequency": 32, + "tgt_max_len": 384 +} \ No newline at end of file diff --git a/sheetsage/weights/0919_02_e0908_oafmelspecnorm/model.pt b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/model.pt new file mode 100644 index 0000000000000000000000000000000000000000..e14cfbda52501e967f4eae6c9f438e72cc14e4ed --- /dev/null +++ b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/model.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7f6dae6902618ba285d78459010a5388002efcd685f1f2ce334297eec6c799f +size 59512452 diff --git a/sheetsage/weights/0919_02_e0908_oafmelspecnorm/step.pkl b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/step.pkl new file mode 100644 index 0000000000000000000000000000000000000000..7ade4748d4c7c79acac29bcddbc11497b137f2fc --- /dev/null +++ b/sheetsage/weights/0919_02_e0908_oafmelspecnorm/step.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06fa1073e4fea8a9af2e5560e11f67fc91b6089d218d872f0b70cad5318fd583 +size 6 diff --git a/sheetsage/weights/0920_00_e0830_jukebox53/e968ecb8349156b2e9761ae61606454988fa614d.cfg.json b/sheetsage/weights/0920_00_e0830_jukebox53/e968ecb8349156b2e9761ae61606454988fa614d.cfg.json new file mode 100644 index 0000000000000000000000000000000000000000..b641906da790ed86cfec47b78d9a032b3475bb41 --- /dev/null +++ b/sheetsage/weights/0920_00_e0830_jukebox53/e968ecb8349156b2e9761ae61606454988fa614d.cfg.json @@ -0,0 +1,19 @@ +{ + "batch_size": 64, + "dataset": "0831_theorytab_beatframebased_jukebox_pitches", + "eval_frequency": 32, + "hacks": [ + "pos_emb", + "4layers", + "octave_invariant_loss", + "pitch_class_loss" + ], + "lr": 0.0001, + "max_num_steps": null, + "model": "transformer", + "seed": 0, + "src": "0919_jukebox53_mean_beat", + "src_max_len": 384, + "summarize_frequency": 32, + "tgt_max_len": 384 +} \ No newline at end of file diff --git a/sheetsage/weights/0920_00_e0830_jukebox53/model.pt b/sheetsage/weights/0920_00_e0830_jukebox53/model.pt new file mode 100644 index 0000000000000000000000000000000000000000..a8377d417d243a2709dece4e3a9fef8ac33535f2 --- /dev/null +++ b/sheetsage/weights/0920_00_e0830_jukebox53/model.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4a2cbce0a5a027e05ac753d72794ca723be2d18312f07daa0e43980d054249e +size 68857462 diff --git a/sheetsage/weights/0920_00_e0830_jukebox53/step.pkl b/sheetsage/weights/0920_00_e0830_jukebox53/step.pkl new file mode 100644 index 0000000000000000000000000000000000000000..27de02f1cbcb4f9a710cf06587603925a83c426c --- /dev/null +++ b/sheetsage/weights/0920_00_e0830_jukebox53/step.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4443a859b4d1fd6f93a5b4351a0056522a12a771f2912b8c308e985c7a0695f1 +size 6 diff --git a/sheetsage/weights/0920_01_e0908_jukebox53/f94f45ed03c8696f187a8bfded0f0d65476b4d48.cfg.json b/sheetsage/weights/0920_01_e0908_jukebox53/f94f45ed03c8696f187a8bfded0f0d65476b4d48.cfg.json new file mode 100644 index 0000000000000000000000000000000000000000..c3c6ed04b00db7907de5348c9c27bca926247072 --- /dev/null +++ b/sheetsage/weights/0920_01_e0908_jukebox53/f94f45ed03c8696f187a8bfded0f0d65476b4d48.cfg.json @@ -0,0 +1,19 @@ +{ + "batch_size": 64, + "dataset": "0908_theorytab_beatframebased_jukebox_chords", + "eval_frequency": 32, + "hacks": [ + "pos_emb", + "4layers", + "octave_invariant_loss", + "pitch_class_loss" + ], + "lr": 0.0001, + "max_num_steps": null, + "model": "transformer", + "seed": 0, + "src": "0919_jukebox53_mean_beat", + "src_max_len": 384, + "summarize_frequency": 32, + "tgt_max_len": 384 +} \ No newline at end of file diff --git a/sheetsage/weights/0920_01_e0908_jukebox53/model.pt b/sheetsage/weights/0920_01_e0908_jukebox53/model.pt new file mode 100644 index 0000000000000000000000000000000000000000..e8a0222ae0fe0af596a007c8dde0eb61a162cb80 --- /dev/null +++ b/sheetsage/weights/0920_01_e0908_jukebox53/model.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8d4641852c1efeae707a6fcf7d6ecddc7e2f33fa8c9753495684ae5b2e352bd +size 68873868 diff --git a/sheetsage/weights/0920_01_e0908_jukebox53/step.pkl b/sheetsage/weights/0920_01_e0908_jukebox53/step.pkl new file mode 100644 index 0000000000000000000000000000000000000000..4e3048e7733ab57844d44d7c65cfc023d44275a9 --- /dev/null +++ b/sheetsage/weights/0920_01_e0908_jukebox53/step.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05f8ed82a062f152fc805dbf3e78996fa3b24d23b719ce90f4f3656e1b292a49 +size 6 diff --git a/sheetsage/weights/oafmelspec_moments.npy b/sheetsage/weights/oafmelspec_moments.npy new file mode 100644 index 0000000000000000000000000000000000000000..7db99079ce90bb1ad671ab4afcae4f6aa4ec8ba4 --- /dev/null +++ b/sheetsage/weights/oafmelspec_moments.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81d20995052676ca4cd60afd2657c8fa0c10e21c0895b39cda85fe3f4d1255e5 +size 1960