Construire un chatbot basé sur Llama2 et OpenVINO™

Auteur : Dr Wu Zhuo, évangéliste Intel OpenVINO, Yang Yicheng, ingénieur logiciel Intel AI

Llama 2 est Meta a publié son dernier modèle de langage à grande échelle. Llama2 est un réseau de neurones artificiels basé sur Transformer qui prend une série de mots en entrée et prédit de manière récursive le mot suivant pour générer du texte. Il s'agit d'un modèle d'intelligence artificielle open source et gratuit. Auparavant, en raison de problèmes d'accord open source, bien que Llama 1 soit puissant, il n'était pas gratuit pour un usage commercial. Cependant, cette fois, Meta a finalement lancé la version commerciale gratuite Llama 2. Profitant de cette occasion, nous partageons comment créer un chatbot basé sur Llama2 et la suite d'outils OpenVINO.

Adresse de l'entrepôt du projet : GitHub - OpenVINO-dev-contest/llama2.openvino : cet exemple montre comment implémenter un modèle basé sur le lama avec l'environnement d'exécution OpenVINO

Remarque 1 : En raison de l'utilisation élevée de la mémoire de Llama2 lors de la conversion et du fonctionnement du modèle, il est recommandé d'utiliser un terminal serveur prenant en charge une mémoire supérieure à 64 Go comme plate-forme de test.

Note 2 : Cet article ne partage que la méthode de déploiement du modèle pré-entraîné Llama2 d'origine. Si vous avez besoin d'obtenir la possibilité de personnaliser les connaissances, vous devez affiner le modèle d'origine ; si vous avez besoin d'obtenir de meilleures performances d'inférence, vous peut utiliser la version du modèle quantifié.

Exportation de modèle

Dans la première étape, nous devons télécharger le modèle Llama2 et l'exporter vers le modèle au format IR pris en charge par OpenVINO™ pour le déploiement. Ici, nous utilisons l'interface fournie par Optimum-Intel pour télécharger et générer le modèle IR directement à partir du référentiel Hugging Face. .

    ov_model = OVModelForCausalLM.from_pretrained(args.model_id,

                                                  compile=False,

                                                  from_transformers=True)

    ov_model.save_pretrained(model_path)

Mais avant cela, nous devons d'abord demander à Meta l'autorisation de télécharger le modèle avant de pouvoir commencer le téléchargement. Pour plus de détails sur la façon d'envoyer la demande, veuillez vous référer aux instructions et aux conseils dans l'entrepôt Llama2 : meta-llama/Llama -2-7b-hf · Visage enlacé

Après avoir exécuté le script export_ir.py dans l'entrepôt du projet , openvino_model.bin et openvino_model.xml seront générés dans le chemin local spécifié , le premier est le fichier de paramètres du modèle et le second est le fichier de structure du modèle .

Déploiement du modèle (Schéma 1)

Étant donné que la bibliothèque Transformer et Optimum de Hugging Face prend déjà en charge le déploiement des modèles de la série Llama2, un moyen relativement simple et rapide consiste à utiliser directement Optimum-Intel pour exécuter l'ensemble du pipeline Llama2, car Optimum a déjà prédéfini des questions et réponses complètes. Le pipeline du modèle de classe : ModelForCausalLM a été profondément intégré, nous n'avons donc besoin d'appeler qu'un petit nombre d'interfaces et pouvons facilement appeler le backend de raisonnement OpenVINO™ pour implémenter un simple déploiement de tâche de réponse aux questions.

ov_model = OVModelForCausalLM.from_pretrained(model_path,

                                                  compile=False,

                                                  device=args.device)

ov_model.compile()

generate_ids = ov_model.generate(inputs.input_ids,

                                 max_length=args.max_sequence_length)



output_text = tokenizer.batch_decode(generate_ids,

                                     skip_special_tokens=True,

                                     clean_up_tokenization_spaces=False)[0]

Voici une brève introduction à ce qu'est Optimum. La bibliothèque Optimum est un outil de déploiement créé par Hugging Face pour aider les développeurs à déployer des modèles à partir des bibliothèques Transformer et Diffuser sur différentes plates-formes matérielles. La bibliothèque Optimum-Intel prend en charge le déploiement sur les plates-formes Intel. Lors de l'utilisation un modèle, la boîte à outils OpenVINO™ est utilisée comme backend d'inférence du modèle pour améliorer les performances des tâches.

L'effet final est le suivant :

Réponse : c'est quoi openvino ?

OpenVINO est un framework logiciel open source pour l'inférence d'apprentissage en profondeur conçu pour fonctionner sur une variété de plates-formes, y compris les processeurs, les GPU et les FPGA. Il est développé par le projet OpenVINO, qui est une collaboration entre Intel et la Linux Foundation.

OpenVINO fournit un ensemble d'outils et de bibliothèques permettant aux développeurs de créer, d'optimiser et de déployer des modèles d'apprentissage en profondeur pour l'inférence. Il prend en charge les frameworks d'apprentissage en profondeur populaires tels que TensorFlow, PyTorch et Caffe, et fournit un certain nombre de fonctionnalités pour améliorer les performances "

Déploiement du modèle (Schéma 2)

Étant donné qu'Optimum appartient toujours au mode "boîte noire", les développeurs ne peuvent pas entièrement personnaliser la logique de fonctionnement interne. La deuxième méthode utilisée ici consiste donc à déployer le modèle Llama2 avec uniquement l'interface native d'OpenVINO™ sans la bibliothèque Optimum, et à reconstruire le pipeline.

L'ensemble du pipeline refactorisé est illustré dans la figure ci-dessous. Des invites seront envoyées à Tokenizer pour la segmentation des mots et l'encodage des vecteurs de mots, puis le raisonnement OpenVINO™ obtiendra les résultats (partie bleue). Lorsque nous arrivons à la partie post-traitement, nous traiterons ensuite les résultats du raisonnement Échantillonnage et décodage, et enfin génération d'informations textuelles régulières. Afin de simplifier le processus ici, seul Top-K est utilisé comme méthode de dépistage.

Figure : Processus de tâche de questions-réponses de Llama2

La majeure partie du code de l'ensemble du pipeline peut être appliquée au processus normal de la tâche de génération de texte. La partie la plus compliquée est le travail de la partie de raisonnement OpenVINO™. Étant donné que la tâche de génération de texte Llama2 doit effectuer plusieurs itérations récursives, et chaque itération aura un cache, Par conséquent, nous devons préparer les données d'entrée appropriées pour différentes itérations. Ensuite, déconstruisons en détail la logique de fonctionnement du modèle :

Figure : Principe d'entrée et de sortie du modèle Llama2

L'entrée du modèle Llama2 se compose principalement de trois parties :

  • input_ids est l'entrée d'invite après la vectorisation
  • L'attention_mask est utilisé pour décrire la longueur des données d'entrée. La valeur attention_mask des input_ids correspondant à la position où les données doivent être calculées est représentée par 1, et les données qui doivent être ignorées pendant le calcul sont représentées par 0.
  • past_key_values.x est une collection d'une série de données utilisées pour enregistrer le cache qui peuvent être partagées à chaque itération.

La sortie du modèle Llama2 se compose de deux parties :

  • Logits est la prédiction du modèle pour le mot suivant ou le jeton suivant
  • present.x peut être considéré comme un cache, directement comme la valeur past_key_values.x de la prochaine itération

L'ensemble du pipeline itérera le modèle Llama2 plusieurs fois pendant l'exécution, et chaque itération générera de manière récursive une prédiction pour le mot suivant dans la réponse jusqu'à ce que la longueur de la réponse finale dépasse la valeur prédéfinie max_sequence_length, ou que le mot suivant prédit soit le terminateur eos_token_id.

  • première itération

Comme le montre la figure, dans une itération (N = 1), input_ids est une phrase d'invite. À ce stade, nous devons également utiliser le tokenizer Tokenizer pour convertir le texte d'origine en un vecteur d'entrée. Étant donné que le cache ne peut pas être utilisé pour l'accélération à ce moment, les séries de vecteurs past_key_values.x sont toutes vides.

  • Nième itération

Lorsque la première itération est terminée, les Logits prédits pour le premier mot de la réponse et les données du cache seront générés. Nous pouvons utiliser ces Logits comme input_ids de la prochaine itération, puis les entrer dans le modèle pour le prochain raisonnement (N =2) , À ce stade, nous pouvons utiliser les données du cache dans la dernière itération, qui est present.x, sans envoyer le "mot de prédiction + indice" complet dans le modèle, réduisant ainsi certains calculs partiellement répétés. De cette façon, il tourne en rond, en entrant le mot de prédiction actuel, ce que l'on appelle une itération, et toutes les réponses peuvent être générées progressivement.

chatbot

En plus de la version de base de Llama 2, Meta a également publié LLaMA-2-chat, qui utilise l'apprentissage par renforcement à partir des commentaires humains pour assurer la sécurité et l'utilité, en particulier pour la création de chatbots. Par rapport au formulaire une question-une-réponse dans le mode modèle question-réponse, le mode chat doit construire un dialogue plus complet. À ce stade, le modèle doit également prendre en compte les informations du dialogue précédent lors de la génération la réponse et l'utiliser comme données de cache Dans les deux sens à chaque itération, nous devons donc ici concevoir un modèle supplémentaire pour construire chaque donnée d'entrée, afin que le modèle puisse pleinement comprendre quels sont les dialogues historiques et quelles sont les nouvelles questions de dialogue.

Figure : Processus de tâche de chat Llama2

Le modèle de texte ici est composé de trois parties : " mots guides + historique + question en cours (invite) " :

  • Mots guides : décrivez la tâche en cours et guidez le modèle pour faire des commentaires appropriés
  • Historique : enregistrez les données de l'historique des discussions, y compris chaque ensemble de questions et de réponses
  • Question actuelle : Semblable aux questions en mode Q&R
def build_inputs(history: list[tuple[str, str]],

                 query: str,

                 system_prompt=DEFAULT_SYSTEM_PROMPT) -> str:

    texts = [f'[INST] <<SYS>>\n{system_prompt}\n<</SYS>>\n\n']

    for user_input, response in history:

        texts.append(

            f'{user_input.strip()} [/INST] {response.strip()} </s><s> [INST] ')

    texts.append(f'{query.strip()} [/INST]')

    return ''.join(texts)

Nous utilisons le framework streamlit pour créer l'interface utilisateur Web et la logique de traitement en arrière-plan du chatbot, et espérons que le chatbot pourra réaliser une interaction en temps réel. L'interaction en temps réel signifie que nous ne voulons pas que le chatbot génère du texte complet, puis le produise dans l'interface visuelle , car cela oblige l'utilisateur à attendre longtemps pour obtenir le résultat, nous espérons que l'utilisateur pourra progressivement voir chaque mot prédit par le modèle et le présenter en séquence au cours du processus d'utilisation. Par conséquent, il est nécessaire d'utiliser le composant TextIteratorStreamer de Hugging Face pour créer un pipeline de traitement de données en continu basé sur celui-ci. Le streamer ici est un objet qui peut être itéré. Je peux obtenir séquentiellement les résultats de prédiction de chaque itération du modèle et convertir les ajouter à leur tour à la réponse finale et présentés étape par étape.

        streamer = TextIteratorStreamer(self.tokenizer,

                                        skip_prompt=True,

                                        skip_special_tokens=True)

        generate_kwargs = dict(model_inputs,

                               streamer=streamer,

                               max_new_tokens=max_generated_tokens,

                               do_sample=True,

                               top_p=top_p,

                               temperature=float(temperature),

                               top_k=top_k,

                               eos_token_id=self.tokenizer.eos_token_id)

        t = Thread(target=self.ov_model.generate, kwargs=generate_kwargs)

        t.start()



        # Pull the generated text from the streamer, and update the model output.

        model_output = ""

        for new_text in streamer:

            model_output += new_text

            yield model_output

        return model_output

Après avoir terminé la construction de la tâche, nous pouvons démarrer la machine de discussion via la commande streamlit run chat_streamlit.py et accéder à l'adresse locale pour les tests. Plusieurs paramètres de configuration communs sont sélectionnés ici pour aider les développeurs à ajuster en fonction de la précision de la réponse du robot :

  • max_tokens : la longueur maximale des phrases générées.
  • top-k : sélectionne aléatoirement les k réponses avec la plus grande confiance. Plus la valeur est élevée, plus le caractère aléatoire de la réponse générée est élevé.
  • top-p : sélectionnez au hasard parmi les réponses dont les probabilités s'additionnent à p. Plus la valeur est élevée, plus le caractère aléatoire des réponses générées est élevé. En général, top-p sera utilisé après top-k.
  • Température : L'échantillonnage contient le caractère aléatoire du modèle génératif, une température élevée signifie plus de caractère aléatoire, ce qui peut aider le modèle à donner une sortie plus créative. Si le modèle commence à s'éloigner du sujet ou donne une sortie absurde, c'est un signe que la température est trop élevée.

Note 3 : Le modèle Llama2 étant relativement volumineux, le temps de chargement et de compilation du premier matériel sera relativement long

Résumer

En tant que grand modèle de langage open source le plus populaire, Llama2 a été reconnu et utilisé par de plus en plus de développeurs en raison de ses excellents résultats dans les principaux tests de référence et de fonctionnalités telles que la prise en charge du réglage fin. L'utilisation d'Optimum-Intel et d'OpenVINO™ pour créer des tâches de la série Llama2 peut encore améliorer les performances de ses modèles sur la plate-forme Intel et abaisser le seuil de déploiement.

Supongo que te gusta

Origin blog.csdn.net/gc5r8w07u/article/details/132059796
Recomendado
Clasificación