forked from langchain-ai/langchain
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GigaChat embeddings example (not working yet)
- Loading branch information
Konstantin Krestnikov
authored and
Konstantin Krestnikov
committed
Jan 9, 2024
1 parent
2234914
commit 112d8ad
Showing
2 changed files
with
1,144 additions
and
0 deletions.
There are no files selected for viewing
306 changes: 306 additions & 0 deletions
306
docs/docs/use_cases/question_answering/gigachat_qa.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,306 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "3ea857b1", | ||
"metadata": {}, | ||
"source": [ | ||
"# Retrieval Augmented Generation(RAG) с использованием GigaChat на примере задачи \"разговор с книгой\"\n", | ||
"\n", | ||
"Подход RAG позволяет большим языковым моделям (LLM) отвечать на вопросы по документам, которы не помещаются в промпт.\n", | ||
"Ниже приведен пример того, как можно научить модель отвечать на вопросы, используя текст из книги \"Мастер и Маргарита\".\n", | ||
"\n", | ||
"Подробнее про RAG вы можете прочитать в [документации LangChain](https://python.langchain.com/docs/use_cases/question_answering/) и в курсе по промпт-инженирингу от Сбера (ссылка будет позже).\n", | ||
"\n", | ||
"В качестве примера мы рассмотрим текст романа Булгакова \"Мастер и Маргарита\" (главы 1 и 2).\n", | ||
"\n", | ||
"Вопрос будет - `Какой плащ был у Понтия Пилата?`. Ответ содержится во второй главе книги:\n", | ||
"`В белом плаще с кровавым подбоем, шаркающей кавалерийской походкой, ранним утром четырнадцатого числа весеннего месяца нисана в крытую колоннаду между двумя крыльями дворца ирода великого вышел прокуратор Иудеи Понтий Пилат.`" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "9ea31150", | ||
"metadata": {}, | ||
"source": [ | ||
"## Установка\n", | ||
"\n", | ||
"Для работы нам понадобится векторая база данных. Мы будем использовать Chroma." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "a7dc1ec5", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%pip install chromadb" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5e7543fa", | ||
"metadata": {}, | ||
"source": [ | ||
"## Инициализация модели\n", | ||
"Теперь инициализируем модель GigaChat." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 29, | ||
"id": "921afeaa", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"Profanity field is deprecated. Use 'profanity_check' instead.\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from langchain.chat_models.gigachat import GigaChat\n", | ||
"\n", | ||
"llm = GigaChat(credentials=...)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "84443c6f", | ||
"metadata": {}, | ||
"source": [ | ||
"Для проверки спросим у модели вопрос про цвет плаща без какого-либо контекста. Возможно, она и так будет давать ожидаемый ответ..." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 39, | ||
"id": "af0398d5", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"'Понтий Пилат, известный как пятый прокуратор Иудеи, действительно носил плащ. Однако, в исторических источниках нет конкретных упоминаний о его плаще. Вероятно, он носил обычный плащ, который был типи'" | ||
] | ||
}, | ||
"execution_count": 39, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"from langchain.schema import HumanMessage\n", | ||
"\n", | ||
"question = \"Какой плащ был у Понтия Пилата?\"\n", | ||
"llm([HumanMessage(content = question)]).content[0:200]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "4b2e4e31", | ||
"metadata": {}, | ||
"source": [ | ||
"Видим, что модель не отвечает так, как нам хотелось бы, поэтому применим RAG-подход.\n", | ||
"\n", | ||
"## Подготовка документа\n", | ||
"\n", | ||
"Для работы с документом нам нужно разделить его на части. Для этого используем `TextLoader` для загрузки книги и `RecursiveCharacterTextSplitter`, чтобы разделить текст на приблизительно равные куски в ~1000 символов с перекрытием в ~200 символов. Этот тип сплиттера сам выбирает каким способом следует оптимально разделять документ (по абзацам, по предложениям и т.д.)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 23, | ||
"id": "f8cf5765", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Total documents: 91\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from langchain.document_loaders import TextLoader\n", | ||
"from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter\n", | ||
"\n", | ||
"loader = TextLoader(\"мастер_и_маргарита.txt\")\n", | ||
"documents = loader.load()\n", | ||
"text_splitter = RecursiveCharacterTextSplitter(\n", | ||
" chunk_size = 1000,\n", | ||
" chunk_overlap = 200,\n", | ||
")\n", | ||
"documents = text_splitter.split_documents(documents)\n", | ||
"print(f\"Total documents: {len(documents)}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "131d5059", | ||
"metadata": {}, | ||
"source": [ | ||
"После нарезки мы получили 91 документ частями книги.\n", | ||
"\n", | ||
"## Создание базы данных эмбеддингов\n", | ||
"\n", | ||
"Эмбеддинг это векторное представление текста, которое может быть использовано для определения смысловой близости текстов. Векторная база данных хранит тексты и соответствующие им эмбеддинги, а также умеет выполнять поиск по ним. Для работы с базой данных мы создаем объект GigaChatEmbeddings и передаем его в базу данных Chroma.\n", | ||
"\n", | ||
"[!NOTE] Параметры `one_by_one_mode` и `_debug_delay` используются для работы в режиме отладки и снижения нагрузки на сервер работы с эммбеддингами." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 24, | ||
"id": "fdce8923", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"Profanity field is deprecated. Use 'profanity_check' instead.\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from langchain.vectorstores import Chroma\n", | ||
"from langchain_community.embeddings import GigaChatEmbeddings\n", | ||
"\n", | ||
"embeddings = GigaChatEmbeddings(\n", | ||
" one_by_one_mode=True,\n", | ||
" _debug_delay=0.005)\n", | ||
"\n", | ||
"from langchain.vectorstores import Chroma\n", | ||
"from chromadb.config import Settings\n", | ||
"db = Chroma.from_documents(documents, embeddings, client_settings=Settings(anonymized_telemetry=False),)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "29137915", | ||
"metadata": {}, | ||
"source": [ | ||
"## Поиск по базе данных\n", | ||
"\n", | ||
"Теперь можно обратиться к базе данных и попросить найти документы, которые с наибольшей вероятностью содержат ответ на наш вопрос.\n", | ||
"\n", | ||
"По-умолчанию база данных возвращает 4 наиболее релевантных документа. Этот параметр можно изменить в зависимости от решаемой задачи и типа документов.\n", | ||
"\n", | ||
"Видно, что первый же документ содержит внутри себя часть книги с ответом на наш вопрос." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 25, | ||
"id": "b0c55e98", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"4" | ||
] | ||
}, | ||
"execution_count": 25, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"docs = db.similarity_search(question, k=4)\n", | ||
"len(docs)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 49, | ||
"id": "32b43339", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"... акцент почему-то пропал: – Все просто: в белом плаще...\\n\\n\\n\\nГлава 2\\n\\nПонтий Пилат\\n\\nВ белом плаще с кровавым подбоем, шаркающей кавалерийской походкой, ранним утром четырнадц ...\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"print(f\"... {str(docs[0])[620:800]} ...\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "96a063c7", | ||
"metadata": {}, | ||
"source": [ | ||
"## QnA цепочка\n", | ||
"\n", | ||
"Теперь мы создадим цепочку QnA, которая специально предназначена для ответов на вопросы по документам. В качестве аргументов есть передается языковая модель и ретривер (база данных)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 27, | ||
"id": "24671e9a", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from langchain.chains import RetrievalQA\n", | ||
"\n", | ||
"qa_chain = RetrievalQA.from_chain_type(\n", | ||
" llm,\n", | ||
" retriever=db.as_retriever()\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 28, | ||
"id": "f3b2f453", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"{'query': 'Какой плащ носил Понтий Пилат?',\n", | ||
" 'result': 'Понтий Пилат носил белый плащ с кровавым подбоем.'}" | ||
] | ||
}, | ||
"execution_count": 28, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"qa_chain({\"query\": question})" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.10.13" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Oops, something went wrong.