- Les chatbots conversationnels de long terme ont du mal à refléter de manière fiable dans leurs réponses les points essentiels des interactions passées, même avec une longue fenêtre de contexte, et cette étude traite d’une méthode pour réduire les problèmes de cohérence grâce à une mémoire par résumés récursifs
- La procédure clé consiste à créer une mémoire initiale à partir d’une courte conversation, puis à la mettre à jour en résumant ensemble la mémoire précédente et la nouvelle conversation à chaque ajout de session afin d’obtenir la mémoire la plus récente
- Les approches fondées sur la recherche dépendent d’un moteur de recherche capable de retrouver précisément les énoncés passés nécessaires, et les approches existantes fondées sur la mémoire peuvent voir des informations obsolètes non mises à jour dégrader la qualité des réponses
- Dans des expériences menées avec des LLM publics et privés comme Llama, ChatGLM et OpenAI GPT-3.5-Turbo, les évaluations automatiques comme humaines montrent une cohérence en conversation longue supérieure aux approches existantes
- Cette méthode peut aussi être utilisée avec de longues fenêtres de contexte ou des LLM renforcés par la recherche, ce qui en fait une option pratique pour gérer des contextes conversationnels très longs sans augmenter aveuglément la longueur totale de la conversation
La mémoire des conversations longues ne se résume pas à un grand contexte
- Les LLM comme GPT-4 et ChatGPT peuvent mener des conversations dynamiques et adaptées au contexte sur des sujets variés, mais dans une conversation longue, ils peuvent perdre des informations passées et produire des réponses incohérentes
- Même si une longue fenêtre de contexte permet de traiter tout l’historique conversationnel en entrée, la capacité à comprendre les interactions passées et à intégrer les informations clés dans la réponse reste limitée
- Les compagnons IA personnels et les services d’assistance en santé sont des cas représentatifs où la mémoire des conversations passées est nécessaire
- Un compagnon IA personnel doit se souvenir des conversations précédentes pour construire une relation
- Un service d’assistance en santé doit prendre en compte l’historique complet des demandes d’un patient afin de fournir des résultats de diagnostic
- Dans un exemple du Multi-Session Chat Dataset, lorsqu’un utilisateur a reparlé du thème passé de la « composition » après environ 20 tours, la version
gpt-turbo-3.5-0301de ChatGPT a répondu qu’elle était un « modèle de langage IA sans profession au sens traditionnel », générant ainsi une réponse incohérente avec son persona précédent
Les limites des approches fondées sur la recherche et sur la mémoire
- Les principales approches pour renforcer les capacités en conversation longue se divisent en approches fondées sur la recherche et approches fondées sur la mémoire
- Les approches fondées sur la recherche conservent les énoncés passés dans un dépôt et utilisent un moteur de recherche pour retrouver l’historique le plus pertinent par rapport à la conversation actuelle afin de générer une réponse
- Leur limite est qu’il est difficile d’obtenir un moteur de recherche idéal capable de capturer complètement le sens nécessaire à la conversation actuelle
- Les approches fondées sur la mémoire résument les conversations passées avec un modèle entraîné séparément ou avec un LLM puissant pour stocker les informations essentielles
- En l’absence d’un mécanisme de mise à jour itératif, des informations obsolètes conservées peuvent nuire directement à la qualité des réponses
- MemoChat reconstruit l’historique des conversations passées par sujet pour chaque locuteur et invite le LLM à rechercher dans une mémoire structurée au moment de la génération
- MemoryBank propose un mécanisme de mémoire qui crée d’abord un résumé de chaque session de conversation avant de les compresser en un résumé global
- Si la mémoire stockée reste totalement figée, il devient difficile de garantir la cohérence avec la conversation en cours
Génération d’une mémoire mise à jour récursivement
- La méthode proposée est un plugin simple dans lequel le LLM lui-même produit des résumés et met continuellement à jour et révise le contexte passé pour stocker des informations en temps réel sur le locuteur
- La procédure se compose de trois étapes
- Un LLM génératif reçoit en entrée un court contexte conversationnel et génère un résumé initial
- Ensuite, la mémoire précédente et les conversations ultérieures sont combinées pour mettre continuellement à jour un nouveau résumé ou une nouvelle mémoire
- Le chatbot utilise la mémoire la plus récente comme référence principale pour répondre à la conversation en cours
- Comme le résumé généré est bien plus court que l’ensemble de la conversation, il est possible de gérer un contexte très long sur plusieurs sessions sans augmenter à grand coût la longueur maximale d’entrée
- La conversation longue est définie comme un Multi-Session Dialogue composé de plusieurs sessions
- On utilise l’ensemble des sessions passées
S = {S1, S2, ..., SN}, le contexte conversationnel de la session actuelleCtet la réponse de référencert - L’objectif est de générer une réponse pertinente et fortement cohérente à partir des sessions passées et du contexte actuel
- On utilise l’ensemble des sessions passées
- La mémoire
Miest la mémoire disponible à la fin de la ie session, et l’ensemble du processus est défini comme un processus séquentiel dans lequel chaque mémoire dépend uniquement de la session actuelle et de la mémoire précédente
Itération de la mémoire et génération de réponses
- La méthode proposée confie deux tâches à n’importe quel LLM
- Itération de la mémoire : résumer récursivement les informations essentielles selon le fil de la conversation longue
- Génération de réponses fondée sur la mémoire : combiner la mémoire la plus récente et la conversation actuelle pour produire une réponse appropriée et cohérente
- L’itération de la mémoire est le processus qui permet d’obtenir un résumé cohérent et à jour que le chatbot peut utiliser
- Certains travaux antérieurs appliquent à la mise à jour de la mémoire des « opérations dures » sur le résumé, comme replace, append et delete
- Cette méthode dépend de conversations de haute qualité annotées avec des labels d’opération, perturbe la cohérence sémantique du résumé et n’est pas adaptée à une gestion de long terme
- La méthode proposée injecte ensemble le contexte conversationnel et la mémoire précédente pour amener le LLM à générer récursivement la mémoire ou le résumé
- L’utilisation du résumé précédent permet au modèle de mieux digérer le contexte conversationnel actuel et de produire une mémoire de haute qualité
- Dans l’exemple, une mémoire initiale est créée après la première session, puis après la deuxième session, une nouvelle information de personnalité — « le bot s’est récemment inscrit dans une nouvelle salle de sport ouverte 24h/24 » — est intégrée à la mémoire précédente
Résultats expérimentaux et possibilités d’application
- Les expériences ont été menées avec des LLM récents, publics et privés, comme Llama, ChatGLM et OpenAI GPT-3.5-Turbo
- Les performances en conversation longue se sont révélées supérieures aux approches populaires existantes tant dans les évaluations automatiques que dans les évaluations humaines
- L’étude valide l’intérêt d’utiliser une mémoire explicite pour les conversations longues, ainsi que le fait que la mémoire générée par la méthode proposée est plus facile à exploiter pour les LLM
- L’ajout de l’apprentissage in-context (ICL) peut encore améliorer la qualité des réponses
- Plusieurs exemples au format
(conversation, mémoire, réponse de référence)sont présentés au LLM - Cela permet au LLM d’utiliser la mémoire générée de manière plus souple
- Plusieurs exemples au format
- Avec
text-davinci-003, le score BLEU s’améliore d’environ +3 % - La méthode proposée complète les LLM à longue fenêtre de contexte comme GPT-3.5-Turbo-16k et LongLoRA-8k, ainsi que les LLM renforcés par la recherche comme LLM-BM25 et LLM-DPR
- Le code public est disponible sur qingyue2014/Rsum
1 commentaires
Avis sur Hacker News
Toutes les approches qui consistent à accumuler de la mémoire dans « l’espace texte » semblent assez bricolées
Pour préserver pleinement le sens du modèle, il paraît plus naturel de stocker cela dans un espace d’embeddings dense plutôt que via une procédure ajoutée qui régénère sans cesse des résumés
En outre, le modèle devrait être entraîné à reconnaître et exploiter la mémoire ; idéalement, il devrait être appris dans ce type de configuration dès le départ
Au final, on lui demande d’ajouter un mot de plus à la conversation donnée, et lorsqu’à un moment il émet un jeton de fin, l’application redonne le contrôle à l’utilisateur
Je pense que l’espace latent et l’espace texte ne sont pas aussi éloignés qu’on pourrait le croire. Les LLM sont assez obtus, mais très doués pour parler ; l’écriture de code ressemble un peu à cela, donc ils s’en sortent bien, alors qu’ils s’effondrent dans les domaines qui demandent une véritable pensée abstraite, comme les maths
Ces hacks dans l’espace texte fonctionnent en fait plutôt bien, et c’est pour cela que des prompts comme « réfléchis étape par étape » sont devenus courants
LoRA est plus proche de la direction évoquée, et excelle à compresser beaucoup de compréhension dans très peu de données. Mais ajuster les poids pour une seule conversation n’est pas encore réaliste, donc pour cet usage on explore l’espace texte
Résumer quelque chose dans sa tête peut paraître « bricolé », mais je pense qu’une grande partie du fonctionnement réel de la mémoire ressemble à cela
https://news.northwestern.edu/stories/2012/09/your-memory-is...
D’après ce que je comprends, les embeddings sont essentiellement proches d’une compression avec perte. Avec un résumé textuel, au moins, l’agent peut vérifier que ce résumé représente correctement l’information d’origine
Chez CodeRabbit, nous utilisons déjà ce type d’approche pour les revues incrémentales de PR et les conversations dans le contexte des changements de code
Cela donne l’impression que le bot dispose de bien plus de contexte qu’en réalité, et c’est l’une des astuces que nous utilisons pour étendre les revues de code par IA à de grosses PR (plus de 100 fichiers)
Pour chaque commit, nous résumons le diff fichier par fichier, puis nous produisons un résumé des résumés, que nous mettons à jour incrémentalement à chaque ajout de commit à la PR. Ce résumé des résumés est stocké discrètement dans les commentaires de la PR, et utilisé lors de la revue de chaque fichier ou pour répondre aux questions des utilisateurs
Une partie du code est open source, et les prompts correspondants utilisés pour le résumé récursif sont ici : https://github.com/coderabbitai/ai-pr-reviewer/blob/main/src...
[0] : coderabbit.ai
Si oui, je me demande aussi si vous avez essayé le function calling au lieu d’analyser une sortie en texte libre
Quand on en est au stade « le code et les scripts seront publiés plus tard », il devient difficile de croire la moindre affirmation
Cela peut être vrai ou être du bullshit, mais s’il n’existe pas de moyen peu coûteux de reproduire l’expérience, je considère ce type d’article comme quelque chose que les auteurs ont écrit pour l’ajouter à leur CV
Dans le domaine des LLM, j’attends depuis plus de six mois des articles promettant « le code sera publié plus tard », sans aucun signe de publication effective. Certains articles sont même assez culottés pour inclure des liens cassés menant à des domaines parqués
Il est temps que la communauté prenne réellement conscience de cette pratique du code non publié
J’avais déjà expérimenté une idée similaire auparavant, en manipulant simplement les prompts à la main dans le tableau de bord de l’API ; cela semblait prometteur, mais ne paraissait pas valoir le coût de l’API. Il est probablement très possible qu’une approche par embeddings vectoriels soit bien meilleure
À titre personnel, dans mon entreprise, nous avons des milliers de « Briefings », des panels hors ligne d’une heure, parfois d’une journée entière
Nous avons réussi à résumer chacun de ces briefings, et des transcriptions brouillonnes ont été bien condensées en résumés de cinq paragraphes
La partie la plus pertinente est que nous avons classé chaque briefing en sujets et sous-sujets selon une relation 1:N. Des dizaines de briefings ont été regroupés par sujet, une douzaine par sous-sujet, puis nous avons à nouveau résumé des sous-ensembles de résumés liés, en testant largement le tout, avec de très bons résultats via les LLM
Au début, j’étais sceptique quant à la faisabilité, mais cela a très bien fonctionné. Si nous avions eu une fenêtre de contexte suffisamment grande, nous n’aurions pas procédé ainsi, mais heureusement cela n’a pas posé problème
Je pense que découper le problème façon MapReduce fonctionne bien mieux que tout fourrer dans une énorme fenêtre de contexte de 32k et demander au modèle de résoudre le tout d’un coup
Il y a quelques mois, j’ai essayé de créer une mémoire par résumé récursif avec un modèle open source, mais implémentée naïvement, elle avait souvent tendance à rester coincée indéfiniment sur certains sujets
Parce que certains fragments survivent à toutes les rondes de résumé
Il est impossible de réduire n’importe quel bloc de texte en un bloc de texte plus petit sans perdre la moindre information
Si c’était possible, cela voudrait dire qu’une compression infinie est possible, et qu’on devrait pouvoir réduire n’importe quel jeu de données à 1 bit puis le restaurer parfaitement. Or ce n’est pas possible
Quand on compresse une conversation en résumé, une partie de l’information disparaît forcément. Peu importe le tuning, les replis ou les méthodes ingénieuses : fondamentalement, il y a perte d’information
En plus, le processus est récursif : à un moment donné, on résume de nouveau un ensemble de résumés, et là encore une certaine quantité d’information disparaît
Donc cela peut aider dans des cas triviaux, mais mettre des résumés récursifs dans le prompt me paraît assez stupide, et si on lui demande de faire quelque chose de réellement utile, cela ne fonctionnera presque certainement pas correctement. Quand on n’utilise pas beaucoup le résumé récursif, on perd peu d’information et cela peut donner l’impression de fonctionner ; mais à l’usage réel, ses limites risquent d’apparaître très vite
Quand on voit à quel point l’esprit humain peut facilement sortir de ses rails à cause d’un traumatisme ou simplement du développement, on mesure combien l’idée d’une IA semblable à l’humain est chargée d’espoir
L’article est un peu décevant. Il n’y a pratiquement aucun détail sur la technique, seulement des tableaux indiquant que leur méthodologie donne de bons résultats
Je sais que c’est courant dans la science actuelle, mais du point de vue d’un développeur qui travaille avec des LLM, l’article a très peu de valeur. Bien sûr, la réputation académique des auteurs en sortira sans doute un peu renforcée, et c’était probablement l’objectif
Ça me donne presque envie de coécrire quelques articles comme ça. Je me demande combien il en faudrait pour pouvoir mettre « ML researcher » tout en haut de mon CV
Ils auraient dû passer bien plus de temps sur les exemples et les prompts
Je l’ai déjà écrit de façon similaire il y a quelques semaines, mais les gens simplifient beaucoup trop la partie résumé : https://news.ycombinator.com/item?id=37117515
La valeur de la mémoire à long terme varie subtilement selon les cas d’usage
Si l’on construit un assistant domestique, il faut identifier les noms avec de la NER, comprendre quel ton la personne préfère quand on lui envoie un message, ainsi que les lieux et les modes de déplacement
Si l’on construit un bot de support client, il faut identifier les demandes qui se transforment en longues conversations ou celles qui mènent à un abandon soudain du panier
Un niveau de résumé général suffit pour faire des démos impressionnantes, mais pour créer aujourd’hui un produit vraiment utile, il faut aller un cran plus loin
Je ne vois pas bien ce qu’il y a de nouveau ici
Le résumé de l’historique de chat basé sur des LLM est une technique bien connue, déjà implémentée dans de nombreux frameworks LLM. Comme dans l’article, résumer à chaque message devient un gros goulot d’étranglement de performance et ajoute une latence importante à la boucle de chat
Beaucoup d’implémentations utilisent un tampon de taille fixe et résument progressivement les anciens blocs de mémoire qui sortent du tampon. Idéalement, ce travail est lui aussi effectué en dehors de la boucle de chat
Je suis l’un des auteurs de Zep, un stockage open source de mémoire à long terme, et nous avons implémenté le résumé de cette façon
0 : https://github.com/getzep/zep
https://github.com/paul-gauthier/aider/blob/main/aider/histo...
https://www.deeplearning.ai/short-courses/langchain-for-llm-...
C’est un peu à côté de l’article ou de la discussion, mais la mémoire courte est bien une limite réelle
Cela dit, la plupart des critiques visant les capacités de GPT-4 s’appliquent tout autant aux humains, voire davantage
Dans une situation de test de Turing inversé, je ne pense pas qu’une personne vivante pourrait me convaincre qu’elle est GPT-4. Rien que par ses réponses rapides et bien structurées, GPT-4 dépasse les capacités humaines
Même si une équipe humaine disposait de 60 minutes pour répondre à chaque question, elle pourrait avoir du mal à égaler les réponses de GPT-4 à des questions intéressantes. Ce serait un concours amusant
L’implémentation de l’article consiste en pratique à ajouter le texte de mémoire comme une partie du prompt
Je me demande pourquoi ils n’utilisent pas un système de stockage et de recherche qui ne consomme pas de tokens de la fenêtre de contexte. Par exemple, au moment du stockage, c’est-à-dire quand le prompt utilisateur arrive, on pourrait classer automatiquement les données par tags, puis, à la recherche, lancer avant la réponse une requête filtrée avec les tags estimés par le LLM
J’ai l’intuition que même quelques règles initiales, comme des noms ou des styles de tags codés en dur, pourraient donner de plutôt bons résultats