Подключение к Saiga2 кастомной базы знаний
Привет Илья,
недавно писал тебе по поводу использования Saiga на GPU, спасибо за комментарий, все получилось! Сейчас есть другой вопрос, уже связанный с Saiga2.
Я делаю кастомного чат-бота на материале русского языка, и не могу никак понять, как мне начать для этого использовать Saiga2 (с первой Saiga все получается). Задача заключается в следующем: у меня есть коллекция документов; документы надо спарсить, обработать, преобразовать в векторную базу данных и подключить к какой-либо генеративной LLM, чтобы с ее помощью на материале (только) этих документов генерить ответы на вопросы пользователя; огромным плюсом будет учет истории и printout токенов по мере их генерации. При этом работать все должно в закрытом контуре, поэтому модель должна быть установлена локально.
Гайдов по этой теме полно, подавляющее большинство из них показывает, как решить подобную задачу с помощью LangChain
. С версией Saiga для llama-cpp
все заработало без вопросов, а вот Saiga2 для llama-cpp
у меня не грузится:
from langchain.llms import LlamaCpp
llm = LlamaCpp(model_path='./models/saiga2_7b_gguf/ggml-model-q8_0.gguf')
Выдает:
ValidationError: 1 validation error for LlamaCpp
__root__
Could not load Llama model from path: ./models/saiga2_7b_gguf/ggml-model-q8_0.gguf. Received error (type=value_error)
Использую LangChain
(а не, например, написанный тобой скрипт) ровно потому, что нужны фичи, которые предоставляет LangChain
: подключение кастомной базы знаний, история etc.
В связи с этим такой вопрос: ты мог бы посоветовать наиболее оптимальный способ для решения моей задачи? Есть ли альтернативы LangChain
, с которыми я мог бы использовать Saiga2 в подобном сценарии? Или, если нет, как мне запустить Saiga2 с LangChain
? Я еще параллельно буду пробовать твой адаптер saiga2_7b_lora, есть ли смысл попробовать использовать его с LangChain.HuggingFacePipeline
?
Заранее спасибо!
Best,
Макс
GGUF - новый формат, для него нужны новые версии биндингов.
Про GGUF уже прочитал, понял :) Это уже, насколько я понял, с langchain.llms.CTransformers
делается?
Нет, это всё та же llama.cpp
Да, на новой версии llama.cpp все получилось.
Но, кстати, сработало и с CTransformers
:
config = {
'temperature': 0,
'context_length': 2000,
'max_new_tokens': 2000,
'stream': True,
'batch_size': 512,
'gpu_layers': 32
}
llm = CTransformers(
model='./models/saiga2_7b_gguf/ggml-model-q8_0.gguf',
config=config
)
Почему может быть такое, что Saiga2 генерит сначала на русском, потом на английском?
Я все делаю с LangChain
, использую HuggingFaceEmbeddings
с моделью all-mpnet-base-v2 (родные эмбеддинги пока использовать не позволяет GPU), историю переписки реализую с ConversationBufferWindowMemory
и заворачиваю это все в ConversationalRetrievalChain
. На первый вопрос ответ на русском, все хорошо, но вот на последующие отвечает на английском, причем ответ в тему (то есть не на рандом).
Я пока что пробую следующие способы (в порядке приоритетности):
- Использовать другие эмбеддинги: чисто для русского языка либо мультиязычные (хотя all-mpnet-base-v2 вроде справляется с русским).
- Промптинг: менять системные промпты самой модели, Chain'ов etc. Кст, промптинг по типу "отвечай только на русском" не дает результатов.
- Другие виды / сочетания Chain'ов (хотя не думаю, что поможет).
Если есть подобный опыт, мог бы ты, пожалуйста, поделиться, в каких еще направлениях стоит покопать и/или в каких не стоит?
Спасибо!
Best,
Макс
А так звучит так, что Langchain промптит на английском, поэтому и ответы на английском
А так звучит так, что Langchain промптит на английском, поэтому и ответы на английском
Я об этом же и подумал, к этому и был мой второй пункт :) просто пока еще не было времени проверить. Тогда в первую очередь посмотрю в том направлении. Спасибо про напоминание про особый промпт для Saiga, проверю первым делом!
Best,
Макс
@maxschmaltz
, привет!
Передо мной сейчас такая же задача: создать бота, который получал бы контекст из документов и отвечал строго по нему. Использую также LangChain, ConversationalRetrievalChain.
Пока что не получается добиться адекватных ответов, просьба "отвечай только по контексту" игнорируется. Думаю, проблема все же в промтах.
Не мог бы ты показать, как реализовал подключение модели, создание промтов, заворачивание в ConversationalRetrievalChain?
Вот моя текущая реализация:
system_template = """
Тебя зовут Сайга. Ты полезный, уважительный и честный ассистент. Для ответа на вопрос пользователя используй информацию из контекста.
Если ты не знаешь ответа, просто скажи, что не знаешь, не пытайся придумать ответ.
Контекст: {context}
Вопрос: {question}
Возвращай только полезный ответ и ничего больше.
Полезный ответ:
"""
llm = LlamaCpp(
model_path=model_path,
n_ctx= 2400,
verbose=True,
use_mlock=True,
n_gpu_layers=12,
n_threads=4,
n_batch=512
)
memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
combine_docs_custom_prompt = PromptTemplate.from_template(system_template)
conversation_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectorstore.as_retriever(),
combine_docs_chain_kwargs=dict(prompt=combine_docs_custom_prompt),
memory=memory,
)
Привет @GolubSeri ,
Прости за поздний ответ. К сожалению, я не могу раскрыть конкретную реализацию, так как она находится в рамках не исследования либо open-source проекта, но продукта для заказчика. Тем не менее, буду рад помочь, дав пару направлений, в которых ты можешь попробовать двинуться.
- Во-первых, бота я делал примерно так же, как ты в своей реализации, так что направление верное. В основном я ссылался на этот гайд (про
ConversationalRetrievalChain
внизу). Следуя ему, я создалquestion_generator
иcombine_docs_chain
и передавал их вместе сmemory
иretriever
вConversationalRetrievalChain
. Для всех Chain'ов использовал Saiga2. Именно такая архитектура помогла улучшить результат. К каждому Chain'у делал кастомный промпт на русском.
Что-то похожее на это:
question_generator = LLMChain(
llm=...,
prompt=...
)
combine_docs_chain = load_qa_with_sources_chain(
llm=...
)
chain = ConversationalRetrievalChain(
memory=...,
retriever=...,
question_generator=question_generator,
combine_docs_chain=combine_docs_chain
)
- Промптинг оказался очень чувствительным, так что пробуй много много разных вариантов. Доходило до того, что реально совершенно менялся результат при добавлении переноса строки, не говоря уже об одном слове. Да и кажется, что модель case-sensitive.
- При дизайне промптов я брал за основу дефолтные промпты от
langchain
, переводил сначала дословно на русский и уже потом допиливал. Например, системный промпт я настраивал около 3-4 часов, перепробовав огромное количество вариантов. В общем, по моему опыту тут чисто калибровка нужна, и промпт влияет куда сильнее, чем все остальное. Опять-таки, конкретного промпта указать не могу, но вот что интересно: добавление изначально рекомендуемого"Ты — Сайга, русскоязычный автоматический ассистент. Ты разговариваешь с людьми и помогаешь им."
как будто сбивало модель и приводило к отсутствию адекватных ответов, когда как те же промпты без него работали куда лучше ( @IlyaGusev , есть идеи, почему так может быть?). Что тут хорошо, это то, что результаты воспроизводимые, так что, нащупав улучшение, сохраняй где-нибудь этот промпт как чекпоинт, сэкономишь время)
Best,
Maкс
Привет @maxschmaltz ,
Большое спасибо, это очень ценно!
Буду экспериментировать дальше :)
Привет
@GolubSeri
Решаю похожую задачу.
Не мог бы ты поделиться своими наработками, пока не могу добиться нормальных ответов?
Привет
@IlyaGusev
Разбираюсь с запуском Saiga2 на GPU, при чем нужно запустить с потоковой генерацией текста.
Подскажешь, пожалуйста, возможно ли это и как можно это осуществить?