from transformers import AutoModelForCausalLM, AutoTokenizer import transformers import torch class Llama2Explainer(): def __init__(self, device) -> None: self.__model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf") self.__tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf") self.__device = device self.__results = {"pos_explain":None, "top_contrastive":None, "other_contrastive":None} self.__pipeline = transformers.pipeline( "text-generation", self.__model, torch_dtype=torch.float16, device_map="auto", ) ## def explain_why(self, original_songs, top_songs, explanation_limit=1): ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0] top10 = ' ,'.join(top_songs) song = "song" if len(original_songs) == 1 else "songs" was = "was" if len(original_songs) == 1 else "were" sentence = "sentence" if explanation_limit == 1 else "sentences" prompt = "[INST] <>\n" +\ "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\ "Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\ "You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\ f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\ + "" +\ "[INST]" +\ "The song that was selected was \"One More Time\" by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\ "\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\ "\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\ "\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\ "[/INST]" +\ "[1]\"Get Lucky\" by Daft Punk was recommended as a song as \"Get Lucky\" comes from the same album as \"One More Time,\" and is by the same artist.\n" +\ "[2]\"Instant Crush\" by Daft Punk & Julian Casablancas was recommended because Daft Punk was also an artist on the song, and is in the same genre.\n" +\ "[3]\"Harder, Better, Faster, Stronger\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +\ "same artist.\n" +\ "[4]\"Around the World\" by Daft Punk was recommended as a song asit comes from the same album as \"One More Time,\" and is by the " +\ "same artist.\n" +\ "[5]\"Je veux te void\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\ "Daft Punk, and was inspired by Daft Punk.\n" +\ "[6]\"Ce jeu\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\ "Daft Punk, and was inspired by Daft Punk.\n" +\ "[7]\"Complètement fou\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\ "Daft Punk, and was inspired by Daft Punk.\n" +\ "[8]\"À cause des garçons\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\ "Daft Punk, and was inspired by Daft Punk.\n" +\ "[9]\"Tristesse / joie\" by Yelle was recommended because the artist is in the same genre as Daft Punk and \"Get Lucky,\" is from the same region as " +\ "Daft Punk, and was inspired by Daft Punk.\n" +\ "[10]\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA is a band in the same genre" +\ " of music as Daft Punk and served as the duo's inspiration.\n" +\ + "" +\ "[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n." + "[/INST]" sequences = self.__pipeline( prompt, do_sample=True, eos_token_id=self.__tokenizer.eos_token_id, max_length=1024, ) self.__results["pos_explain"] = sequences[0]['generated_text'].split("/INST] ")[-1] ## def explain_why_not_these_songs(self, original_songs, selected_songs, other_songs, explanation_limit=1): ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0] top10 = ' ,'.join(selected_songs) next10 = ' ,'.join(other_songs) song = "song" if len(original_songs) == 1 else "songs" song2 = "song" if len(other_songs) == 1 else "songs" was = "was" if len(original_songs) == 1 else "were" sentence = "sentence" if explanation_limit == 1 else "sentences" prompt = "[INST] <>\n" +\ "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\ "Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\ "You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\ f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\ + "" +\ "[INST]" +\ "The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\ "\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\ "\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\ "\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\ "The following songs were not recommended: \"False Kings\" by Poets of the Fall, " + "\"Day Seven: Hope\" by Ayreon, " +\ "\"9 väärää kättä\" by Apulanta, K-Magg, " + "\"Simple and Clean\" by Hikaru Utada." +\ "[/INST]" +\ "[1] \"Technopolis - Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra was recommended because YELLOW MAGIC ORCHESTRA " +\ "is a band that influenced Daft Punk\'s work. Based on your song selection, we chose to recommend more songs " +\ "like Daft Punk instead of work that may be inspired by the work of Daft Punk.\n" +\ "[2] \"I Wanna Be Yours\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\ " with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\ "[3] \"Thunder\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +\ "so they were selected to be lower on the list.\n" +\ "[4] \"Why\'d You Only Call Me When You\'re High?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\ " with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\ "[5] \"Do I Wanna Know?\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\ " with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\ "[6] \"Believer\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated with alt-rock than electronic music, " +\ "so they were selected to be lower on the list.\n" +\ "[7] \"The Less I Know The Better\" by Tame Impala was selected as Tame Impala are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+\ "their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list.\n" +\ "[8] \"Stressed Out\" by Twenty One Pilots as Twenty One Pilots are associated with electronic-rock genres. They use a mix of rock and electronic instruments throughout "+\ "their music. Since they also use a rock genre, and Daft Punk is more electronic, they were recommended lower on the list." +\ "[9] \"505\" by Arctic Monkeys was selected because Arctic Monkeys are popular artists similar to Daft Punk, but are more associated " +\ " with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\ "[10] \"Natural\" by Imagine Dragons was selected because Imagine Dragons are popular artists similar to Daft Punk, but are more associated " +\ " with alt-rock than electronic music, so they were selected to be lower on the list.\n" +\ + "" +\ "[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following {song2} were not recommended: " +\ f"{next10}\n" + "[/INST]" sequences = self.__pipeline( prompt, do_sample=True, eos_token_id=self.__tokenizer.eos_token_id, max_length=1024, ) self.__results["top_constrastive"] = sequences[0]['generated_text'].split("/INST] ")[-1] ## def explain_why_not_these_songs(self, original_songs, selected_songs, other_songs, explanation_limit=1): ss_str = ' ,'.join(original_songs) if len(original_songs) > 1 else original_songs[0] top10 = ' ,'.join(selected_songs) others = ' ,'.join(other_songs) song = "song" if len(original_songs) == 1 else "songs" song2 = "song" if len(other_songs) == 1 else "songs" was = "was" if len(original_songs) == 1 else "were" sentence = "sentence" if explanation_limit == 1 else "sentences" prompt = "[INST] <>\n" +\ "You are an audiophile who knows the intricacies of many genres and the nuances for why a person might prefer one genre of music over another. " +\ "Your job is to help explain to the user why these songs in particular were chosen and why other songs that are closely related were not selected. " +\ "You will be given either a song or a list of songs and will also be given the top 10 recommendations from Spotify based on the original song or list of " +\ f"songs. You should explain why each of the songs was chosen to the best of your ability in the order they appear in {explanation_limit} {sentence} per song.\n" +\ + "" +\ "[INST]" +\ "The song that was selected was “One More Time” by Daft Punk. The top 10 recommended songs include: \"Get Lucky\" by Daft Punk, " +\ "\"Instant Crush\" by Daft Punk & Julian Casablancas, \"Harder, Better, Faster, Stronger\" by Daft Punk, \"Around the World\" by Daft Punk, " +\ "\"Je veux te void\" by Yelle, \"Ce jeu\" by Yelle, \"Complètement fou\" by Yelle, \"À cause des garçons\" by Yelle, \"Tristesse / joie\" by Yelle, " +\ "\"Rydeen -Original Mix\" by YELLOW MAGIC ORCHESTRA and Video Game Orchestra.\n" +\ "The following songs were not recommended: \"False Kings\" by Poets of the Fall, " + "\"Day Seven: Hope\" by Ayreon, " +\ "\"9 väärää kättä\" by Apulanta, K-Magg, " + "\"Simple and Clean\" by Hikaru Utada." +\ "[/INST]" +\ "[1]\"False Kings\" by Poets of the Fall wasn't recommended as the genres are not similar. They are also from different nations, as " +\ "Daft Punk is from France and Poets of the Fall is from Finland. Their core inspirations are also different.\n" +\ "[2]\"Day Seven: Hope\" by Ayreon wasn't recommended as the genres do not align. Ayreon is a heavy metal group while Daft Punk is an " +\ "electronic group.\n" +\ "[3]\"9 väärää kättä\" by Apulanta, K-Magg wasn't recommended as the song is entirely sung in Finnish, where as Daft Punk typically " +\ "features English vocals or melodic beats only.\n"+\ "[4]\"Simple and Clean\" by Hikaru Utada was not recommended as the genres do not align. Simple and Clean is a J-Pop song, while " +\ "\"One More Time\" is an electronic song." +\ + "" +\ "[INST]" + f"The {song} that {was} selected {was} {ss_str}. The top 10 recommended songs include: {top10}\n. The following {song2} were not recommended: " +\ f"{others}\n" + "[/INST]" sequences = self.__pipeline( prompt, do_sample=True, eos_token_id=self.__tokenizer.eos_token_id, max_length=1024, ) self.__results["other_constrastive"] = sequences[0]['generated_text'].split("/INST] ")[-1] ## def get_constrastive_explanations(self): if self.__results["top_contrastive"] is None: return "Run the explainer first!" return self.__results["top_contrastive"] ## def get_other_constrastive_explanations(self): if self.__results["other_contrastive"] is None: return "Run the explainer first!" return self.__results["other_contrastive"] ## def get_positive_explanations(self): if self.__results["pos_explain"] is None: return "Run the explainer first!" return self.__results["pos_explain"] ## ##