Память чат-бота: реализуйте свой собственный алгоритм с нуля
2 ноября 2024 г.Введение
Есть одна проблема при реализации собственного чат-бота, и это управление памятью во время разговора. Конечно, вы можете использовать готовые библиотеки, такие как 'Langchain', 'Ollama' и т. д... Но что, если вы хотите реализовать свой собственный алгоритм с нуля?
Мы представляем здесь подход к управлению кратковременной памятью в чат-ботах, используя комбинацию методов хранения и автоматического резюмирования для оптимизации разговорного контекста. Представленный метод опирается на динамическую структуру памяти, которая ограничивает размер данных, сохраняя при этом важную информацию с помощью интеллектуальных резюмирований.
Такой подход не только улучшает текучесть взаимодействий, но и обеспечивает контекстную непрерывность во время длительных сеансов диалога. Более того, использование асинхронных методов гарантирует, что операции управления памятью не будут мешать отзывчивости чат-бота.
Математическое моделирование управления разговором
В этом разделе мы математически формализуем управление памятью разговора в чат-боте. Память структурирована как список пар, представляющих обмены между пользователем и ботом.
Не волнуйтесь, эта часть довольно проста и позволяет нам просто смоделировать основные механизмы, чтобы затем перенести их в код.
Структура памяти разговора
Память разговора можно определить как упорядоченный список пар (u_i, d_i), где u_i представляет собой ввод пользователя, а d_i — ответ бота для i^th обмена. Этот список обозначается как C:
C = [(u1, d1), (u2, d2), ..., (un, dn)]
Где n — общее количество обменов в текущей истории.
Обновление памяти
При возникновении нового обмена в память добавляется новая пара (u_{n+1}, d_{n+1}). Если размер C превышает предопределенный максимальный предел M_max, самый старый обмен удаляется:
C = if |C| < M_max:
C ∪ {(u_{n+1}, d_{n+1})}
else:
(C \\ {(u1, d1)}) ∪ {(u_{n+1}, d_{n+1})}
Количество слов
Чтобы управлять пространством памяти и решать, когда необходимо сжатие, мы вычисляем общее количество слов W(C) в памяти:
W(C) = Σ (|ui| + |di|)
Где |ui| и |di| — количество слов в ui и di соответственно.
Сжатие памяти
Когда W(C) превышает пороговое значение W_max, память сжимается для сохранения релевантного контекста. Это сжатие выполняется моделью резюмирования S, такой как BART:
C_сжатый = S(C)
Где C_compressed — это обобщенная версия памяти, сокращающая общее количество слов, но сохраняющая суть прошлых взаимодействий.
Реализация кода для управления памятью чат-бота
В этом разделе мы рассмотрим пример кода Python, иллюстрирующий управление памятью в чат-боте. Код использует PyTorch и трансформеры Hugging Face для управления и сжатия истории разговора.
Настройка среды
Начнем с проверки доступности графического процессора, что позволит при необходимости ускорить обработку.
import torch from transformers import pipeline import logging
if torch.cuda.is_available():
device: int = 0
else:
device: int = -1
MAX_MEMORY_SIZE: int = 2000
Определение класса ChatbotMemory
Класс ChatbotMemory управляет историей разговоров и выполняет операции обновления и сжатия. Каждый раз, когда вызывается update_memory, текст памяти подсчитывается и обрабатывается по мере необходимости.
class ChatbotMemory:
def init(self, conv: list = []):
self.conversation_history = conv
def update_memory(self, user_input: str, bot_response: str) -> None:
self.conversation_history.append(f"'user': {user_input}, 'bot': {bot_response}")
if memory_counter(self.conversation_history) > 1000:
self.conversation_history = compressed_memory(self.conversation_history)
logging.info("Memory compressed.")
if len(self.conversation_history) > MAX_MEMORY_SIZE:
self.conversation_history.pop(0)
logging.info("Memory reduced.")
return 0
def get_memory(self):
return self.conversation_history
Сжатие памяти и подсчет
Функция _get_compressed_memory использует модель BART для обобщения истории разговоров.
def _get_compressed_memory(sentence: str) -> str:
summarizer = pipeline("summarization", model="facebook/bart-large-cnn", device=device)
summary = summarizer(sentence, max_length=50, min_length=5, do_sample=False)
return summary[0]['summary_text']
Функция compress_memory применяет функцию _get_compressed_memory к каждому сегменту истории разговора. Это оптимизируется путем обработки партиями. Этот метод отделен от _get_compressed_memory, чтобы обеспечить введение новых методов сжатия.
def compressed_memory(conv_hist: list) -> list:
return [_get_compressed_memory(' '.join(conv_hist[i:i+5])) for i in range(0, len(conv_hist), 5)]
Функция memory_counter подсчитывает общее количество слов в истории. (Обратите внимание, что может быть интересно выполнить этот шаг с токенами вместо слов.)
def memory_counter(conv_hist: list) -> int:
st = ''.join(conv_hist)
return len(st.split())
Заключение
Этот код устанавливает эффективную структуру для управления памятью в чат-боте, используя методы сжатия для поддержания релевантного контекста и повышения общей производительности системы. Использование моделей резюмирования, таких как BART, гарантирует, что даже при сжатии памяти сохраняется существенный контекст.
Надеюсь, эта небольшая демонстрация помогла вам понять, что моделировать общие процессы и внедрять их в код довольно просто. Это базовый, но важный шаг, который позволяет вам понять, как все работает:
- 1: Я определяю все шаги действия
- 2: Я моделирую их математически
- 3: код!
Код на GitHub
Оригинал