В эпоху, когда конфиденциальность данных имеет первостепенное значение, создание собственной языковой модели (LLM) является важным решением как для компаний, так и для частных лиц. Это руководство предназначено для того, чтобы помочь вам пройти процесс создания собственного чат-бота с использованием Ollama , Python 3 и ChromaDB , которые размещаются локально в вашей системе. Вот основные причины, по которым вам нужен этот урок:
Это руководство поможет вам создать надежного и безопасного локального чат-бота, адаптированного к вашим потребностям, без ущерба для конфиденциальности и контроля.
Генерация с расширенным поиском (RAG) — это усовершенствованный метод, который сочетает в себе сильные стороны поиска информации и генерации текста для создания более точных и контекстуально релевантных ответов. Вот описание того, как работает RAG и почему это выгодно:
RAG — это гибридная модель, которая расширяет возможности языковых моделей за счет включения внешней базы знаний или хранилища документов. Процесс включает в себя два основных компонента:
Настроив локальное приложение RAG с такими инструментами, как Ollama, Python и ChromaDB, вы сможете воспользоваться преимуществами расширенных языковых моделей, сохраняя при этом контроль над своими данными и параметрами настройки.
Запуск больших языковых моделей (LLM), подобных тем, которые используются в поисково-дополненной генерации (RAG), требует значительных вычислительных мощностей. Одним из ключевых компонентов, обеспечивающих эффективную обработку и внедрение данных в эти модели, является графический процессор (GPU). Вот почему графические процессоры необходимы для этой задачи и как они влияют на производительность вашей локальной установки LLM:
Графический процессор — это специализированный процессор, предназначенный для ускорения рендеринга изображений и видео. В отличие от центральных процессоров (ЦП), которые оптимизированы для задач последовательной обработки, графические процессоры превосходно справляются с параллельной обработкой. Это делает их особенно подходящими для сложных математических вычислений, необходимых для моделей машинного обучения и глубокого обучения.
При настройке локального LLM выбор графического процессора может существенно повлиять на производительность. Вот некоторые факторы, которые следует учитывать:
Инвестиции в высокопроизводительный графический процессор имеют решающее значение для локального запуска моделей LLM. Это обеспечивает более быструю обработку данных, эффективное обучение модели и быстрое генерирование ответов, что делает ваше локальное приложение RAG более устойчивым и надежным. Используя возможности графических процессоров, вы можете в полной мере реализовать преимущества размещения собственного чат-бота, адаптированного к вашим конкретным потребностям и требованиям конфиденциальности данных.
Прежде чем приступить к настройке, убедитесь, что у вас есть следующие предварительные условия:
Чтобы установить и настроить нашу среду Python 3, выполните следующие действия: Загрузите и установите Python 3 на свой компьютер. Затем убедитесь, что ваш Python 3 установлен и успешно работает:
$ python3 --version # Python 3.11.7
Создайте папку для своего проекта, например, local-rag
:
$ mkdir local-rag $ cd local-rag
Создайте виртуальную среду с именем venv
:
$ python3 -m venv venv
Активируйте виртуальную среду:
$ source venv/bin/activate # Windows # venv\Scripts\activate
Установите ChromaDB с помощью pip:
$ pip install --q chromadb
Установите инструменты Langchain для беспрепятственной работы с вашей моделью:
$ pip install --q unstructured langchain langchain-text-splitters $ pip install --q "unstructured[all-docs]"
Установите Flask, чтобы использовать ваше приложение в качестве службы HTTP:
$ pip install --q flask
Чтобы установить Ollama, выполните следующие действия: Перейдите на страницу загрузки Ollama и загрузите установщик для вашей операционной системы. Проверьте установку Ollama, выполнив:
$ ollama --version # ollama version is 0.1.47
Выберите нужную вам модель LLM. Например, чтобы использовать модель Mistral:
$ ollama pull mistral
Извлеките модель внедрения текста. Например, чтобы использовать модель Nomic Embed Text:
$ ollama pull nomic-embed-text
Затем запустите свои модели Олламы:
$ ollama serve
Теперь, когда вы настроили свою среду с использованием Python, Ollama, ChromaDB и других зависимостей, пришло время создать собственное локальное приложение RAG. В этом разделе мы рассмотрим практический код Python и предоставим обзор того, как структурировать ваше приложение.
app.py
Это основной файл приложения Flask. Он определяет маршруты для внедрения файлов в базу данных векторов и получения ответа от модели.
import os from dotenv import load_dotenv load_dotenv() from flask import Flask, request, jsonify from embed import embed from query import query from get_vector_db import get_vector_db TEMP_FOLDER = os.getenv('TEMP_FOLDER', './_temp') os.makedirs(TEMP_FOLDER, exist_ok=True) app = Flask(__name__) @app.route('/embed', methods=['POST']) def route_embed(): if 'file' not in request.files: return jsonify({"error": "No file part"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "No selected file"}), 400 embedded = embed(file) if embedded: return jsonify({"message": "File embedded successfully"}), 200 return jsonify({"error": "File embedded unsuccessfully"}), 400 @app.route('/query', methods=['POST']) def route_query(): data = request.get_json() response = query(data.get('query')) if response: return jsonify({"message": response}), 200 return jsonify({"error": "Something went wrong"}), 400 if __name__ == '__main__': app.run(host="0.0.0.0", port=8080, debug=True)
embed.py
Этот модуль управляет процессом внедрения, включая сохранение загруженных файлов, загрузку и разделение данных, а также добавление документов в базу данных векторов.
import os from datetime import datetime from werkzeug.utils import secure_filename from langchain_community.document_loaders import UnstructuredPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from get_vector_db import get_vector_db TEMP_FOLDER = os.getenv('TEMP_FOLDER', './_temp') # Function to check if the uploaded file is allowed (only PDF files) def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'pdf'} # Function to save the uploaded file to the temporary folder def save_file(file): # Save the uploaded file with a secure filename and return the file path ct = datetime.now() ts = ct.timestamp() filename = str(ts) + "_" + secure_filename(file.filename) file_path = os.path.join(TEMP_FOLDER, filename) file.save(file_path) return file_path # Function to load and split the data from the PDF file def load_and_split_data(file_path): # Load the PDF file and split the data into chunks loader = UnstructuredPDFLoader(file_path=file_path) data = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=7500, chunk_overlap=100) chunks = text_splitter.split_documents(data) return chunks # Main function to handle the embedding process def embed(file): # Check if the file is valid, save it, load and split the data, add to the database, and remove the temporary file if file.filename != '' and file and allowed_file(file.filename): file_path = save_file(file) chunks = load_and_split_data(file_path) db = get_vector_db() db.add_documents(chunks) db.persist() os.remove(file_path) return True return False
query.py
Этот модуль обрабатывает запросы пользователей, генерируя несколько версий запроса, извлекая соответствующие документы и предоставляя ответы на основе контекста.
import os from langchain_community.chat_models import ChatOllama from langchain.prompts import ChatPromptTemplate, PromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough from langchain.retrievers.multi_query import MultiQueryRetriever from get_vector_db import get_vector_db LLM_MODEL = os.getenv('LLM_MODEL', 'mistral') # Function to get the prompt templates for generating alternative questions and answering based on context def get_prompt(): QUERY_PROMPT = PromptTemplate( input_variables=["question"], template="""You are an AI language model assistant. Your task is to generate five different versions of the given user question to retrieve relevant documents from a vector database. By generating multiple perspectives on the user question, your goal is to help the user overcome some of the limitations of the distance-based similarity search. Provide these alternative questions separated by newlines. Original question: {question}""", ) template = """Answer the question based ONLY on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) return QUERY_PROMPT, prompt # Main function to handle the query process def query(input): if input: # Initialize the language model with the specified model name llm = ChatOllama(model=LLM_MODEL) # Get the vector database instance db = get_vector_db() # Get the prompt templates QUERY_PROMPT, prompt = get_prompt() # Set up the retriever to generate multiple queries using the language model and the query prompt retriever = MultiQueryRetriever.from_llm( db.as_retriever(), llm, prompt=QUERY_PROMPT ) # Define the processing chain to retrieve context, generate the answer, and parse the output chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) response = chain.invoke(input) return response return None
get_vector_db.py
Этот модуль инициализирует и возвращает экземпляр векторной базы данных, используемый для хранения и извлечения внедренных документов.
import os from langchain_community.embeddings import OllamaEmbeddings from langchain_community.vectorstores.chroma import Chroma CHROMA_PATH = os.getenv('CHROMA_PATH', 'chroma') COLLECTION_NAME = os.getenv('COLLECTION_NAME', 'local-rag') TEXT_EMBEDDING_MODEL = os.getenv('TEXT_EMBEDDING_MODEL', 'nomic-embed-text') def get_vector_db(): embedding = OllamaEmbeddings(model=TEXT_EMBEDDING_MODEL,show_progress=True) db = Chroma( collection_name=COLLECTION_NAME, persist_directory=CHROMA_PATH, embedding_function=embedding ) return db
Создайте файл .env
для хранения переменных среды:
TEMP_FOLDER = './_temp' CHROMA_PATH = 'chroma' COLLECTION_NAME = 'local-rag' LLM_MODEL = 'mistral' TEXT_EMBEDDING_MODEL = 'nomic-embed-text'
Запустите файл app.py
, чтобы запустить сервер приложений:
$ python3 app.py
После запуска сервера вы можете начать отправлять запросы к следующим конечным точкам:
$ curl --request POST \ --url http://localhost:8080/embed \ --header 'Content-Type: multipart/form-data' \ --form file=@/Users/nassermaronie/Documents/Nasser-resume.pdf # Response { "message": "File embedded successfully" }
$ curl --request POST \ --url http://localhost:8080/query \ --header 'Content-Type: application/json' \ --data '{ "query": "Who is Nasser?" }' # Response { "message": "Nasser Maronie is a Full Stack Developer with experience in web and mobile app development. He has worked as a Lead Full Stack Engineer at Ulventech, a Senior Full Stack Engineer at Speedoc, a Senior Frontend Engineer at Irvins, and a Software Engineer at Tokopedia. His tech stacks include Typescript, ReactJS, VueJS, React Native, NodeJS, PHP, Golang, Python, MySQL, PostgresQL, MongoDB, Redis, AWS, Firebase, and Supabase. He has a Bachelor's degree in Information System from Universitas Amikom Yogyakarta." }
Следуя этим инструкциям, вы сможете эффективно запускать собственное локальное приложение RAG и взаимодействовать с ним, используя Python, Ollama и ChromaDB, адаптированные к вашим потребностям. Настраивайте и расширяйте функциональность по мере необходимости, чтобы расширить возможности вашего приложения.
Используя возможности локального развертывания, вы не только защищаете конфиденциальную информацию, но также оптимизируете производительность и скорость реагирования. Независимо от того, улучшаете ли вы взаимодействие с клиентами или оптимизируете внутренние процессы, локально развернутое приложение RAG предлагает гибкость и надежность, позволяющие адаптироваться и расти вместе с вашими требованиями.
https://github.com/firstpersoncode/local-rag
Приятного кодирования!