Distribuisci MusicGen in pochissimo tempo con i Punti di Inferenza
Distribuisci MusicGen rapidamente con i Punti di Inferenza
MusicGen è un potente modello di generazione musicale che prende in input un prompt di testo e, opzionalmente, una melodia per produrre musica in output. Questo post sul blog ti guiderà nella generazione di musica con MusicGen utilizzando i punti di inferenza.
I punti di inferenza ci permettono di scrivere funzioni di inferenza personalizzate chiamate gestori personalizzati. Questi sono particolarmente utili quando un modello non è supportato di default dalla libreria di astrazione di alto livello transformers
.
Le pipeline di transformers
offrono potenti astrazioni per eseguire inferenze con modelli basati su transformers
. I punti di inferenza sfruttano l’API delle pipeline per distribuire facilmente i modelli con pochi clic. Tuttavia, i punti di inferenza possono anche essere utilizzati per distribuire modelli che non hanno una pipeline, o addirittura modelli non-transformer! Questo viene realizzato utilizzando una funzione di inferenza personalizzata che chiamiamo gestore personalizzato.
Dimostriamo questo processo utilizzando MusicGen come esempio. Per implementare una funzione di gestione personalizzata per MusicGen e distribuirla, dovremo:
- Sei Credenze Che Rendono Il Tuo Lavoro In Data Science Pieno Di Preconcetti
- OpenAI svela 6 entusiasmanti funzionalità di ChatGPT per rivoluzionare l’esperienza dell’utente
- Classificazione Multietichetta Un’introduzione con Scikit-Learn di Python
- Duplicare il repository di MusicGen che vogliamo servire,
- Scrivere un gestore personalizzato in
handler.py
e le relative dipendenze inrequirements.txt
e aggiungerli al repository duplicato, - Creare un punto di inferenza per quel repository.
O semplicemente utilizzare il risultato finale e distribuire il nostro repository di modelli MusicGen personalizzato, dove abbiamo seguito i passaggi precedenti 🙂
Andiamo!
Prima di tutto, duplicheremo il repository facebook/musicgen-large nel nostro profilo utilizzando il duplicatore di repository.
Successivamente, aggiungeremo handler.py
e requirements.txt
al repository duplicato. Prima di tutto, diamo un’occhiata a come eseguire l’inferenza con MusicGen.
from transformers import AutoProcessor, MusicgenForConditionalGeneration
processor = AutoProcessor.from_pretrained("facebook/musicgen-large")
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-large")
inputs = processor(
text=["brano pop degli anni '80 con bassi e sintetizzatore"],
padding=True,
return_tensors="pt",
)
audio_values = model.generate(**inputs, do_sample=True, guidance_scale=3, max_new_tokens=256)
Ascoltiamo come suona:
Il tuo browser non supporta l’elemento audio.
Opzionalmente, puoi anche condizionare l’output con un frammento audio, ad esempio generare un frammento complementare che combina l’audio generato dal testo con un audio di input.
from transformers import AutoProcessor, MusicgenForConditionalGeneration
from datasets import load_dataset
processor = AutoProcessor.from_pretrained("facebook/musicgen-large")
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-large")
dataset = load_dataset("sanchit-gandhi/gtzan", split="train", streaming=True)
sample = next(iter(dataset))["audio"]
# prendiamo la prima metà del campione audio
sample["array"] = sample["array"][: len(sample["array"]) // 2]
inputs = processor(
audio=sample["array"],
sampling_rate=sample["sampling_rate"],
text=["brano blues degli anni '80 con sassofono funky"],
padding=True,
return_tensors="pt",
)
audio_values = model.generate(**inputs, do_sample=True, guidance_scale=3, max_new_tokens=256)
Diamo un’ascoltata:
Il tuo browser non supporta l’elemento audio.
In entrambi i casi, il metodo model.generate
produce l’audio e segue gli stessi principi della generazione di testo. Puoi leggere di più al riguardo nel nostro post sul blog su come generare musica.
Bene! Con l’uso di base descritto sopra, distribuiamo MusicGen per divertimento e profitto!
Prima di tutto, definiremo un gestore personalizzato in handler.py
. Possiamo utilizzare il modello di template dei punti di inferenza e sovrascrivere i metodi __init__
e __call__
con il nostro codice di inferenza personalizzato. __init__
inizializzerà il modello e il processore, e __call__
prenderà i dati e restituirà la musica generata. Troverai la classe EndpointHandler
modificata qui di seguito. 👇
from typing import Dict, List, Any
from transformers import AutoProcessor, MusicgenForConditionalGeneration
import torch
class EndpointHandler:
def __init__(self, path=""):
# carica il modello e il processore dal percorso
self.processor = AutoProcessor.from_pretrained(path)
self.model = MusicgenForConditionalGeneration.from_pretrained(path, torch_dtype=torch.float16).to("cuda")
def __call__(self, data: Dict[str, Any]) -> Dict[str, str]:
"""
Args:
data (:dict:):
Il payload con il prompt di testo e i parametri di generazione.
"""
# elabora l'input
inputs = data.pop("inputs", data)
parameters = data.pop("parameters", None)
# preelaborazione
inputs = self.processor(
text=[inputs],
padding=True,
return_tensors="pt",).to("cuda")
# passa gli input con tutti i kwargs nei dati
if parameters is not None:
with torch.autocast("cuda"):
outputs = self.model.generate(**inputs, **parameters)
else:
with torch.autocast("cuda"):
outputs = self.model.generate(**inputs,)
# post-elaborazione della previsione
prediction = outputs[0].cpu().numpy().tolist()
return [{"generated_audio": prediction}]
Per mantenere le cose semplici, in questo esempio stiamo solo generando audio a partire dal testo, senza condizionarlo con una melodia. Successivamente, creeremo un file requirements.txt
contenente tutte le dipendenze necessarie per eseguire il nostro codice di inferenza:
transformers==4.31.0
accelerate>=0.20.3
Caricare questi due file nel nostro repository sarà sufficiente per servire il modello.
Ora possiamo creare il punto di accesso all’inferenza. Vai alla pagina dei punti di accesso all’inferenza e clicca su Deploy your first model
. Nel campo “Model repository”, inserisci l’identificatore del tuo repository duplicato. Quindi seleziona l’hardware desiderato e crea il punto di accesso. Qualsiasi istanza con almeno 16 GB di RAM dovrebbe funzionare per musicgen-large
.
Dopo aver creato il punto di accesso, verrà avviato automaticamente e sarà pronto per ricevere richieste.
Possiamo interrogare il punto di accesso con il seguente snippet.
curl URL_DEL_PUNTO_DI_ACCESSO \
-X POST \
-d '{"inputs":"canzone folk allegra, vivace e allegra"}' \
-H "Authorization: {YOUR_TOKEN_HERE}" \
-H "Content-Type: application/json"
Possiamo vedere la seguente sequenza di forme d’onda come output.
[{"generated_audio":[[-0.024490159,-0.03154691,-0.0079551935,-0.003828604, ...]]}]
Ecco come suona:
Il tuo browser non supporta l’elemento audio.
Puoi anche colpire il punto di accesso con la classe InferenceClient
della libreria Python huggingface-hub
.
from huggingface_hub import InferenceClient
client = InferenceClient(model = URL_DEL_PUNTO_DI_ACCESSO)
response = client.post(json={"inputs":"una canzone rock alternativa"})
# la risposta sarà simile a questa b'[{"generated_text":[[-0.182352,-0.17802449, ...]]}]
output = eval(response)[0]["generated_audio"]
Puoi convertire la sequenza generata in audio nel modo che preferisci. Puoi usare scipy
in Python per scriverla su un file .wav.
import scipy
import numpy as np
# output è [[-0.182352,-0.17802449, ...]]
scipy.io.wavfile.write("musicgen_out.wav", rate=32000, data=np.array(output[0]))
E voilà!
Gioca con la demo qui sotto per provare il punto di accesso.
Conclusioni
In questo post del blog, abbiamo mostrato come distribuire MusicGen utilizzando i punti di accesso all’inferenza con un gestore di inferenza personalizzato. La stessa tecnica può essere utilizzata per qualsiasi altro modello nell’Hub che non abbia una pipeline associata. Tutto ciò che devi fare è sovrascrivere la classe Endpoint Handler
in handler.py
e aggiungere requirements.txt
per riflettere le dipendenze del tuo progetto.
Per saperne di più
- Documentazione sui punti di accesso all’inferenza che copre il gestore personalizzato