🚀 Prova Zilliz Cloud, la versione completamente gestita di Milvus, gratuitamente—sperimenta prestazioni 10 volte più veloci! Prova Ora>>

milvus-logo
LFAI
  • Home
  • Blog
  • Accelerare la generazione di candidati nei sistemi di raccomandazione usando Milvus e PaddlePaddle

Accelerare la generazione di candidati nei sistemi di raccomandazione usando Milvus e PaddlePaddle

  • Scenarios
November 26, 2021
Yunmei

Se avete esperienza nello sviluppo di un sistema di raccomandazione, è probabile che siate stati vittime di almeno uno dei seguenti problemi:

  • Il sistema è estremamente lento nel restituire i risultati a causa dell'enorme quantità di set di dati.
  • I nuovi dati inseriti non possono essere elaborati in tempo reale per la ricerca o l'interrogazione.
  • L'implementazione del sistema di raccomandazione è scoraggiante.

Questo articolo si propone di affrontare i problemi sopra menzionati e di fornire alcuni spunti di riflessione introducendo un progetto di sistema di raccomandazione di prodotti che utilizza Milvus, un database vettoriale open-source, abbinato a PaddlePaddle, una piattaforma di deep learning.

Questo articolo si propone di descrivere brevemente il flusso di lavoro minimo di un sistema di raccomandazione. Poi passa a presentare i componenti principali e i dettagli di implementazione di questo progetto.

Il flusso di lavoro di base di un sistema di raccomandazione

Prima di addentrarci nel progetto stesso, diamo prima un'occhiata al flusso di lavoro di base di un sistema di raccomandazione. Un sistema di raccomandazione può restituire risultati personalizzati in base agli interessi e alle esigenze dell'utente. Per creare tali raccomandazioni personalizzate, il sistema passa attraverso due fasi, la generazione dei candidati e la classificazione.

2.png 2.png

La prima fase è la generazione dei candidati, che restituisce i dati più rilevanti o simili, come un prodotto o un video che corrisponde al profilo dell'utente. Durante la generazione dei candidati, il sistema confronta le caratteristiche dell'utente con i dati memorizzati nel suo database e recupera quelli simili. Poi, durante la classificazione, il sistema assegna un punteggio e riordina i dati recuperati. Infine, i risultati in cima alla lista vengono mostrati agli utenti.

Nel nostro caso di un sistema di raccomandazione di prodotti, il sistema confronta innanzitutto il profilo dell'utente con le caratteristiche dei prodotti in inventario per filtrare un elenco di prodotti che rispondono alle esigenze dell'utente. Quindi il sistema assegna un punteggio ai prodotti in base alla loro somiglianza con il profilo dell'utente, li classifica e infine restituisce all'utente i 10 prodotti migliori.

3.png 3.png

Architettura del sistema

Il sistema di raccomandazione dei prodotti di questo progetto utilizza tre componenti: MIND, PaddleRec e Milvus.

MIND

MIND, acronimo di "Multi-Interest Network with Dynamic Routing for Recommendation at Tmall", è un algoritmo sviluppato da Alibaba Group. Prima della proposta di MIND, la maggior parte dei modelli di AI prevalenti per la raccomandazione utilizzava un singolo vettore per rappresentare i vari interessi di un utente. Tuttavia, un singolo vettore non è sufficiente a rappresentare esattamente gli interessi di un utente. Pertanto, è stato proposto l'algoritmo MIND per trasformare gli interessi multipli di un utente in diversi vettori.

In particolare, MIND adotta una rete multi-interesse con routing dinamico per elaborare gli interessi multipli di un utente durante la fase di generazione dei candidati. La rete multi-interesse è un livello di estrattore multi-interesse costruito su un meccanismo di instradamento a capsula. Può essere utilizzata per combinare i comportamenti passati di un utente con i suoi interessi multipli, per fornire un profilo utente accurato.

Il diagramma seguente illustra la struttura della rete di MIND.

4.png 4.png

Per rappresentare le caratteristiche degli utenti, MIND prende in input i comportamenti e gli interessi degli utenti e li inserisce nel livello di embedding per generare vettori di utenti, tra cui vettori di interessi e vettori di comportamenti degli utenti. I vettori di comportamento dell'utente vengono poi inseriti nel livello di estrazione multi-interesse per generare capsule di interessi degli utenti. Dopo aver concatenato le capsule di interesse dell'utente con gli embedding del comportamento dell'utente e aver utilizzato diversi livelli ReLU per trasformarli, MIND produce diversi vettori di rappresentazione dell'utente. Questo progetto ha definito che MIND produrrà quattro vettori di rappresentazione dell'utente.

D'altra parte, i tratti dei prodotti passano attraverso il livello di embedding e vengono convertiti in vettori di elementi sparsi. Quindi ogni vettore di elementi passa attraverso un livello di pooling per diventare un vettore denso.

Quando tutti i dati sono convertiti in vettori, viene introdotto un ulteriore livello di attenzione label-aware per guidare il processo di addestramento.

PaddleRec

PaddleRec è una libreria di modelli di ricerca su larga scala per la raccomandazione. Fa parte dell'ecosistema Baidu PaddlePaddle. PaddleRec mira a fornire agli sviluppatori una soluzione integrata per costruire un sistema di raccomandazione in modo semplice e rapido.

5.png 5.png

Come accennato nel paragrafo iniziale, gli ingegneri che sviluppano sistemi di raccomandazione devono spesso affrontare le sfide della scarsa usabilità e della complicata implementazione del sistema. Tuttavia, PaddleRec può aiutare gli sviluppatori nei seguenti aspetti:

  • Facilità d'uso: PaddleRec è una libreria open-source che racchiude diversi modelli popolari nel settore, tra cui quelli per la generazione di candidati, il ranking, il reranking, il multitasking e altri ancora. Con PaddleRec è possibile testare immediatamente l'efficacia del modello e migliorarne l'efficienza attraverso l'iterazione. PaddleRec offre un modo semplice per addestrare modelli per sistemi distribuiti con prestazioni eccellenti. È ottimizzato per l'elaborazione di dati su larga scala di vettori sparsi. È possibile scalare facilmente PaddleRec in orizzontale e accelerare la sua velocità di calcolo. Pertanto, è possibile creare rapidamente ambienti di addestramento su Kubernetes utilizzando PaddleRec.

  • Supporto per la distribuzione: PaddleRec offre soluzioni di distribuzione online per i suoi modelli. I modelli sono immediatamente pronti per l'uso dopo la formazione, con flessibilità e alta disponibilità.

Milvus

Milvus è un database vettoriale con un'architettura cloud-native. È open source su GitHub e può essere utilizzato per memorizzare, indicizzare e gestire vettori di incorporamento massivi generati da reti neurali profonde e altri modelli di apprendimento automatico (ML). Milvus incapsula diverse librerie di prima classe per la ricerca approssimata dei vicini (ANN), tra cui Faiss, NMSLIB e Annoy. È inoltre possibile scalare Milvus in base alle proprie esigenze. Il servizio Milvus è altamente disponibile e supporta l'elaborazione batch e stream unificata. Milvus si impegna a semplificare il processo di gestione dei dati non strutturati e a fornire un'esperienza utente coerente in diversi ambienti di distribuzione. Ha le seguenti caratteristiche:

  • Elevate prestazioni quando si effettuano ricerche vettoriali su enormi insiemi di dati.

  • Una comunità di sviluppatori che offre supporto multilingue e toolchain.

  • Scalabilità nel cloud ed elevata affidabilità anche in caso di interruzioni.

  • Ricerca ibrida ottenuta accoppiando il filtraggio scalare con la ricerca di similarità vettoriale.

In questo progetto viene utilizzato Milvus per la ricerca di similarità vettoriale e la gestione dei vettori, perché è in grado di risolvere il problema dei frequenti aggiornamenti dei dati mantenendo la stabilità del sistema.

Implementazione del sistema

Per realizzare il sistema di raccomandazione dei prodotti in questo progetto, è necessario seguire le seguenti fasi:

  1. Elaborazione dei dati
  2. Formazione del modello
  3. Test del modello
  4. Generazione di candidati di articoli di prodotto
    1. Memorizzazione dei dati: i vettori degli articoli sono ottenuti attraverso il modello addestrato e sono memorizzati in Milvus.
    2. Ricerca dei dati: quattro vettori utente generati da MIND vengono inseriti in Milvus per la ricerca di similarità vettoriale.
    3. Classificazione dei dati: ognuno dei quattro vettori ha i propri top_k vettori di elementi simili, e quattro gruppi di vettori top_k vengono classificati per restituire un elenco finale di top_k vettori più simili.

Il codice sorgente di questo progetto è ospitato sulla piattaforma Baidu AI Studio. La sezione seguente illustra in dettaglio il codice sorgente di questo progetto.

Fase 1. Elaborazione dei dati

Il dataset originale proviene dal dataset di libri Amazon fornito da ComiRec. Tuttavia, questo progetto utilizza i dati scaricati ed elaborati da PaddleRec. Per ulteriori informazioni, consultare il dataset AmazonBook nel progetto PaddleRec.

Il dataset per l'addestramento dovrebbe apparire nel seguente formato, con ogni colonna che rappresenta:

  • Uid: ID utente.
  • item_id: ID del prodotto cliccato dall'utente.
  • Time: Il timestamp o l'ordine di clic.

Il set di dati per il test dovrebbe apparire nel seguente formato, con ogni colonna che rappresenta:

  • Uid: ID utente.

  • hist_item: ID dell'articolo del prodotto nel comportamento storico di clic dell'utente. Quando ci sono più hist_item, sono ordinati in base al timestamp.

  • eval_item: La sequenza effettiva in cui l'utente fa clic sui prodotti.

Fase 2. Formazione del modello

L'addestramento del modello utilizza i dati elaborati nella fase precedente e adotta il modello di generazione dei candidati, MIND, costruito su PaddleRec.

1. Input del modello

In dygraph_model.py, eseguire il seguente codice per elaborare i dati e trasformarli in input del modello. Questo processo ordina gli elementi cliccati dallo stesso utente nei dati originali in base al timestamp e li combina per formare una sequenza. Quindi, seleziona casualmente un item``_``id dalla sequenza come target_item, ed estrae i 10 elementi precedenti a target_item come hist_item per l'input del modello. Se la sequenza non è sufficientemente lunga, può essere impostata a 0. seq_len dovrebbe essere la lunghezza effettiva della sequenza hist_item.

def create_feeds_train(self, batch_data):
    hist_item = paddle.to_tensor(batch_data[0], dtype="int64")
    target_item = paddle.to_tensor(batch_data[1], dtype="int64")
    seq_len = paddle.to_tensor(batch_data[2], dtype="int64")
    return [hist_item, target_item, seq_len]

Fare riferimento allo script /home/aistudio/recommend/model/mind/mind_reader.py per il codice di lettura del dataset originale.

2. Collegamento in rete del modello

Il codice seguente è un estratto di net.py. class Mind_Capsual_Layer definisce il livello di estrazione multi-interesse costruito sul meccanismo di instradamento delle capsule di interesse. La funzione label_aware_attention() implementa la tecnica di attenzione label-aware dell'algoritmo MIND. La funzione forward() in class MindLayer modella le caratteristiche dell'utente e genera i vettori di peso corrispondenti.

class Mind_Capsual_Layer(nn.Layer):
    def __init__(self):
        super(Mind_Capsual_Layer, self).__init__()
        self.iters = iters
        self.input_units = input_units
        self.output_units = output_units
        self.maxlen = maxlen
        self.init_std = init_std
        self.k_max = k_max
        self.batch_size = batch_size
        # B2I routing
        self.routing_logits = self.create_parameter(
            shape=[1, self.k_max, self.maxlen],
            attr=paddle.ParamAttr(
                name="routing_logits", trainable=False),
            default_initializer=nn.initializer.Normal(
                mean=0.0, std=self.init_std))
        # bilinear mapping
        self.bilinear_mapping_matrix = self.create_parameter(
            shape=[self.input_units, self.output_units],
            attr=paddle.ParamAttr(
                name="bilinear_mapping_matrix", trainable=True),
            default_initializer=nn.initializer.Normal(
                mean=0.0, std=self.init_std))
                
class MindLayer(nn.Layer):

    def label_aware_attention(self, keys, query):
        weight = paddle.sum(keys * query, axis=-1, keepdim=True)
        weight = paddle.pow(weight, self.pow_p)  # [x,k_max,1]
        weight = F.softmax(weight, axis=1)
        output = paddle.sum(keys * weight, axis=1)
        return output, weight

    def forward(self, hist_item, seqlen, labels=None):
        hit_item_emb = self.item_emb(hist_item)  # [B, seqlen, embed_dim]
        user_cap, cap_weights, cap_mask = self.capsual_layer(hit_item_emb, seqlen)
        if not self.training:
            return user_cap, cap_weights
        target_emb = self.item_emb(labels)
        user_emb, W = self.label_aware_attention(user_cap, target_emb)

        return self.sampled_softmax(
            user_emb, labels, self.item_emb.weight,
            self.embedding_bias), W, user_cap, cap_weights, cap_mask

Per la struttura specifica della rete MIND si rimanda allo script /home/aistudio/recommend/model/mind/net.py.

3. Ottimizzazione del modello

Questo progetto utilizza l'algoritmo Adam come ottimizzatore del modello.

def create_optimizer(self, dy_model, config):
    lr = config.get("hyper_parameters.optimizer.learning_rate", 0.001)
    optimizer = paddle.optimizer.Adam(
        learning_rate=lr, parameters=dy_model.parameters())
    return optimizer

Inoltre, PaddleRec scrive gli iperparametri in config.yaml, quindi è sufficiente modificare questo file per vedere un chiaro confronto tra l'efficacia dei due modelli e migliorare l'efficienza del modello. Durante l'addestramento del modello, lo scarso effetto del modello può derivare dall'underfitting o dall'overfitting del modello. È quindi possibile migliorarlo modificando il numero di cicli di addestramento. In questo progetto, è sufficiente modificare il parametro epochs in config.yaml per trovare il numero perfetto di cicli di addestramento. Inoltre, è possibile modificare anche l'ottimizzatore del modello, optimizer.class o learning_rate per il debug. Di seguito sono riportati alcuni dei parametri di config.yaml.

runner:
  use_gpu: True
  use_auc: False
  train_batch_size: 128
  epochs: 20
  print_interval: 10
  model_save_path: "output_model_mind"

# hyper parameters of user-defined network
hyper_parameters:
  # optimizer config
  optimizer:
    class: Adam
    learning_rate: 0.005

Per un'implementazione dettagliata si rimanda allo script /home/aistudio/recommend/model/mind/dygraph_model.py.

4. Formazione del modello

Eseguire il seguente comando per avviare l'addestramento del modello.

python -u trainer.py -m mind/config.yaml

Fare riferimento a /home/aistudio/recommend/model/trainer.py per il progetto di formazione del modello.

Passo 3. Test del modello

Questa fase utilizza un set di dati di prova per verificare le prestazioni, come il tasso di richiamo del modello addestrato.

Durante il test del modello, tutti i vettori degli item vengono caricati dal modello e poi importati in Milvus, il database vettoriale open source. Leggere il dataset di test attraverso lo script /home/aistudio/recommend/model/mind/mind_infer_reader.py. Caricare il modello nella fase precedente e inserire il dataset di prova nel modello per ottenere quattro vettori di interesse dell'utente. Cercare i 50 vettori di elementi più simili ai quattro vettori di interesse in Milvus. È possibile consigliare agli utenti i risultati restituiti.

Eseguire il seguente comando per testare il modello.

python -u infer.py -m mind/config.yaml -top_n 50

Durante il test del modello, il sistema fornisce diversi indicatori per valutarne l'efficacia, come Recall@50, NDCG@50 e HitRate@50. Questo articolo introduce la modifica di un solo parametro. Tuttavia, nel proprio scenario applicativo, è necessario addestrare più epoche per migliorare l'efficacia del modello. È possibile migliorare l'efficacia del modello anche utilizzando ottimizzatori diversi, impostando tassi di apprendimento diversi e aumentando il numero di cicli di test. Si consiglia di salvare più modelli con effetti diversi e di scegliere quello con le prestazioni migliori e più adatto alla propria applicazione.

Fase 4. Generazione di candidati di articoli di prodotto

Per creare il servizio di generazione di candidati di prodotto, questo progetto utilizza il modello addestrato nelle fasi precedenti, abbinato a Milvus. Durante la generazione dei candidati, si utilizza FASTAPI per fornire l'interfaccia. Quando il servizio si avvia, è possibile eseguire direttamente i comandi nel terminale tramite curl.

Eseguire il seguente comando per generare candidati preliminari.

uvicorn main:app

Il servizio fornisce quattro tipi di interfacce:

  • Inserisci: Eseguire il seguente comando per leggere i vettori di elementi dal modello e inserirli in una collezione in Milvus.
curl -X 'POST' \
  'http://127.0.0.1:8000/rec/insert_data' \
  -H 'accept: application/json' \
  -d ''
  • Genera candidati preliminari: Inserisce la sequenza in cui i prodotti vengono cliccati dall'utente e scopre il prodotto successivo che l'utente può cliccare. È anche possibile generare candidati di prodotti in lotti per diversi utenti in una sola volta. hist_item nel comando seguente è un vettore bidimensionale, e ogni riga rappresenta una sequenza di prodotti che l'utente ha cliccato in passato. È possibile definire la lunghezza della sequenza. Anche i risultati restituiti sono insiemi di vettori bidimensionali, ogni riga rappresenta i prodotti item idrestituiti dagli utenti.
curl -X 'POST' \
  'http://127.0.0.1:8000/rec/recall' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "top_k": 50,
  "hist_item": [[43,23,65,675,3456,8654,123454,54367,234561],[675,3456,8654,123454,76543,1234,9769,5670,65443,123098,34219,234098]]
}'
  • Interrogare il numero totale di articoli del prodotto: Eseguire il seguente comando per ottenere il numero totale di vettori di articoli memorizzati nel database Milvus.
curl -X 'POST' \
  'http://127.0.0.1:8000/rec/count' \
  -H 'accept: application/json' \
  -d ''
  • Cancellare: Eseguire il seguente comando per cancellare tutti i dati memorizzati nel database Milvus.
curl -X 'POST' \
  'http://127.0.0.1:8000/qa/drop' \
  -H 'accept: application/json' \
  -d ''

Se si esegue il servizio di generazione dei candidati sul proprio server locale, è possibile accedere alle interfacce di cui sopra anche all'indirizzo 127.0.0.1:8000/docs. Si può giocare facendo clic sulle quattro interfacce e inserendo i valori dei parametri. Quindi fare clic su "Prova" per ottenere il risultato della raccomandazione.

6.png 6.png

7.png 7.png

Ricapitolazione

Questo articolo si concentra principalmente sulla prima fase della generazione dei candidati nella costruzione di un sistema di raccomandazione. Fornisce anche una soluzione per accelerare questo processo combinando Milvus con l'algoritmo MIND e PaddleRec e quindi ha affrontato il problema proposto nel paragrafo iniziale.

Cosa succede se il sistema è estremamente lento nel restituire i risultati a causa dell'enorme quantità di set di dati? Milvus, il database vettoriale open-source, è stato progettato per una ricerca di similarità rapidissima su dataset vettoriali densi, contenenti milioni, miliardi o addirittura trilioni di vettori.

E se i nuovi dati inseriti non possono essere elaborati in tempo reale per la ricerca o l'interrogazione? È possibile utilizzare Milvus in quanto supporta l'elaborazione batch e stream unificata e consente di cercare e interrogare i dati appena inseriti in tempo reale. Inoltre, il modello MIND è in grado di convertire in tempo reale i nuovi comportamenti degli utenti e di inserire istantaneamente i vettori utente in Milvus.

E se l'implementazione complicata è troppo intimidatoria? PaddleRec, una potente libreria appartenente all'ecosistema PaddlePaddle, può fornirvi una soluzione integrata per implementare il vostro sistema di raccomandazione o altre applicazioni in modo semplice e rapido.

L'autore

Yunmei Li, Data Engineer di Zilliz, si è laureata in informatica presso la Huazhong University of Science and Technology. Da quando è entrata a far parte di Zilliz, ha lavorato all'esplorazione di soluzioni per il progetto open source Milvus e ha aiutato gli utenti ad applicare Milvus in scenari reali. La sua attenzione principale è rivolta all'NLP e ai sistemi di raccomandazione e vorrebbe approfondire ulteriormente queste due aree. Le piace passare il tempo da sola e leggere.

Cercate altre risorse?

Like the article? Spread the word

Continua a Leggere