У уроці про пошукові застосунки ми коротко ознайомилися з тим, як інтегрувати власні дані у Велику Мовну Модель (LLM). У цьому уроці ми докладніше розглянемо концепцію підкріплення ваших даних у вашому застосунку LLM, механіку процесу та методи зберігання даних, включно з ембеддінгами і текстом.
Відео незабаром
У цьому уроці ми розглянемо наступне:
-
Вступ до RAG: що це таке і чому його використовують в ШІ (штучний інтелект).
-
Розуміння векторних баз даних і створення однієї для нашого застосунку.
-
Практичний приклад інтеграції RAG у застосунок.
Після проходження уроку ви зможете:
-
Пояснити значення RAG у витяганні та обробці даних.
-
Налаштувати застосунок RAG і закріпити ваші дані за LLM.
-
Ефективно інтегрувати RAG і векторні бази даних у застосунки LLM.
Для цього уроку ми хочемо додати власні нотатки в освітній стартап, що дозволить чатботу отримувати більше інформації з різних предметів. Використовуючи нотатки, учні зможуть краще вчитися та розуміти різні теми, що полегшить підготовку до іспитів. Для нашого сценарію ми використаємо:
-
Azure OpenAI:LLM, який ми використаємо для створення чатбота -
Урок «ШІ для початківців» про нейронні мережі:дані, на яких ми базуватимемо нашу LLM -
Azure AI SearchтаAzure Cosmos DB:векторна база даних для зберігання наших даних і створення пошукового індексу
Користувачі зможуть створювати практичні тести зі своїх нотаток, повторювальні флеш-картки та стисло узагальнювати інформацію. Але спочатку розглянемо, що таке RAG і як він працює:
Чатбот на основі LLM обробляє користувацькі запити для генерації відповідей. Він розрахований на інтерактивність і взаємодію з користувачами з багатьох тем. Проте його відповіді обмежені контекстом, що надається та початковими навчальними даними. Наприклад, знання GPT-4 зрізані станом на вересень 2021 року, тож він не володіє інформацією про події після цієї дати. Крім того, дані, використані для навчання LLM, не включають конфіденційну інформацію, таку як особисті нотатки або інструкції з продукту компанії.
Припустимо, ви хочете розгорнути чатбота, який створює тести з ваших нотаток — вам буде потрібне підключення до бази знань. Саме тут RAG допомагає. RAG працюють так:
-
База знань: Перед витягом ці документи потрібно імпортувати та обробити, зазвичай розбиваючи великі документи на менші частини, перетворюючи їх у текстові ембеддинги та зберігаючи у базі даних.
-
Користувацький запит: користувач ставить запитання
-
Витяг: коли користувач задає запит, модель ембеддингів витягує релевантну інформацію з бази знань, щоб надати додатковий контекст, який буде включено до запиту.
-
Збагачене покоління: LLM покращує свою відповідь на основі витягнутих даних. Це дозволяє генерувати відповіді не лише на базі попередньо навчених даних, але і з врахуванням релевантної інформації з доданого контексту. Витягнута інформація використовується для збагачення відповідей LLM. LLM потім повертає відповідь на запит користувача.
Архітектура RAG реалізована за допомогою трансформерів, що складається з двох частин: енкодера та декодера. Наприклад, коли користувач задає питання, вхідний текст «кодується» у вектори, що захоплюють значення слів, а вектори «декодуються» у наш індекс документів і генерують новий текст на основі запиту користувача. LLM використовує модель енкодера-декодера для створення відповіді.
Два підходи до реалізації RAG за пропозицією з роботи: Retrieval-Augmented Generation for Knowledge intensive NLP Tasks такі:
-
RAG-Sequence — використання витягнутих документів для передбачення найкращої можливої відповіді на запит користувача
-
RAG-Token — використання документів для генерації наступного токена, а потім їх витяг для відповіді на запит користувача
-
Багатство інформації: забезпечує актуальність та оновленість текстових відповідей. Це покращує продуктивність у специфічних доменах завдяки доступу до внутрішньої бази знань.
-
Зменшує вигадки, використовуючи перевірені дані у базі знань для надання контексту користувацьким запитам.
-
Це економічно вигідно, оскільки є більш доступним ніж тонке налаштування LLM.
Наш застосунок базується на наших особистих даних, тобто на уроці про нейронні мережі з курсу AI For Beginners.
Векторна база даних, на відміну від традиційних баз, спеціалізована для зберігання, керування та пошуку вбудованих векторів. Вона зберігає числові представлення документів. Поділ даних на числові ембеддинги полегшує нашій системі ШІ розуміння і обробку цих даних.
Ми зберігаємо наші ембеддинги у векторних базах даних, бо LLM має обмеження на кількість токенів, які приймає на вхід. Оскільки неможливо передати всю ембеддингову інформацію одночасно, нам потрібно розбивати її на частини, і коли користувач ставить запит, найрелевантніші ембеддинги повертаються разом із запитом. Розбиття також знижує витрати на кількість токенів, що передаються LLM.
Популярні векторні бази даних: Azure Cosmos DB, Clarifyai, Pinecone, Chromadb, ScaNN, Qdrant і DeepLake. Ви можете створити модель Azure Cosmos DB за допомогою Azure CLI такою командою:
az login
az group create -n <resource-group-name> -l <location>
az cosmosdb create -n <cosmos-db-name> -r <resource-group-name>
az cosmosdb list-keys -n <cosmos-db-name> -g <resource-group-name>Перед збереженням даних їх потрібно конвертувати у векторні ембеддинги. Якщо ви працюєте з великими документами або довгими текстами, можна розділити їх на частини відповідно до очікуваних запитів. Розбиття можна робити на рівні речень або абзаців. Оскільки розбиття базується на значенні слів навколо, ви можете додати додатковий контекст до частини, наприклад заголовок документа або деякий текст перед чи після неї. Ви можете розбивати дані так:
def split_text(text, max_length, min_length):
words = text.split()
chunks = []
current_chunk = []
for word in words:
current_chunk.append(word)
if len(' '.join(current_chunk)) < max_length and len(' '.join(current_chunk)) > min_length:
chunks.append(' '.join(current_chunk))
current_chunk = []
# Якщо останній шматок не досяг мінімальної довжини, все одно додайте його
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunksПісля розбиття текст можна вбудувати, використовуючи різні моделі ембеддінгів. Деякі з них: word2vec, ada-002 від OpenAI, Azure Computer Vision та інші. Вибір моделі залежить від використовуваних мов, типу закодованого контенту (текст/зображення/аудіо), розміру вхідних даних і довжини вихідного ембеддингу.
Приклад ембеддінгу тексту за допомогою моделі text-embedding-ada-002 від OpenAI:

Коли користувач задає запит, ретрівер конвертує його у вектор за допомогою енкодера запитів, а потім шукає у нашому пошуковому індексі документи з релевантними векторами, пов’язаними із запитом. Після цього він перетворює і вхідний вектор, і вектори документів у текст і передає їх в LLM.
Витяг відбувається, коли система намагається швидко знайти документи в індексі, що відповідають критеріям пошуку. Мета ретривера — отримати документи, які використовуватимуться для надання контексту і закріплення LLM на ваших даних.
Існує декілька способів пошуку у базі даних:
-
Пошук за ключовими словами – для текстових запитів
-
Векторний пошук – конвертує документи з тексту у векторні представлення за допомогою моделей ембеддінгів, що дозволяє виконувати семантичний пошук на основі значення слів. Витяг відбуватиметься шляхом пошуку документів, чий векторний профіль найближчий до запитання користувача.
-
Гібридний – комбінація пошуку за ключовими словами та векторного пошуку.
Проблема виникає, коли у базі немає схожої відповіді на запит — система поверне найкращу доступну інформацію. Ви можете використовувати тактику, таку як налаштування максимальної відстані релевантності або гібридний пошук, який поєднує ключові слова і векторний пошук. У цьому уроці ми користуємося гібридним пошуком, комбінуючи обидва методи. Ми збережемо наші дані у датафрейм з колонками, що містять частини тексту і відповідні ембеддинги.
Ретрівер шукатиме у базі знань ембеддинги, що розташовані близько один до одного — найближчого сусіда, оскільки це схожі тексти. Коли користувач ставить запит, він спочатку кодується у ембеддинг і порівнюється з іншими подібними ембеддингами. Загальновживана міра схожості — косинусна близькість, яка базується на куті між двома векторами.
Для вимірювання схожості можна також використовувати евклідову відстань — пряму лінію між кінцями векторів, або скалярний добуток, який вимірює суму добутків відповідних елементів двох векторів.
Для виконання витягу потрібно побудувати пошуковий індекс для бази знань. Індекс зберігатиме ембеддинги та швидко знаходитиме найбільш схожі частини навіть у великій базі. Ми можемо створити індекс локально так:
from sklearn.neighbors import NearestNeighbors
embeddings = flattened_df['embeddings'].to_list()
# Створити індекс пошуку
nbrs = NearestNeighbors(n_neighbors=5, algorithm='ball_tree').fit(embeddings)
# Щоб виконати запит до індексу, можна використовувати метод kneighbors
distances, indices = nbrs.kneighbors(embeddings)Після запиту до бази вам може знадобитись упорядкувати результати за релевантністю. LLM для переупорядкування використовує машинне навчання, щоб покращити релевантність результатів, розташовуючи їх від найрелевантніших. В Azure AI Search переупорядкування виконується автоматично за допомогою семантичного ранжувальника. Приклад роботи переупорядкування з використанням найближчих сусідів:
# Знайти найбільш схожі документи
distances, indices = nbrs.kneighbors([query_vector])
index = []
# Вивести найбільш схожі документи
for i in range(3):
index = indices[0][i]
for index in indices[0]:
print(flattened_df['chunks'].iloc[index])
print(flattened_df['path'].iloc[index])
print(flattened_df['distances'].iloc[index])
else:
print(f"Index {index} not found in DataFrame")Останній крок — додати наш LLM, щоб отримувати відповіді, підкріплені нашими даними. Реалізуємо це так:
user_input = "what is a perceptron?"
def chatbot(user_input):
# Перетворити питання на вектор запиту
query_vector = create_embeddings(user_input)
# Знайти найбільш схожі документи
distances, indices = nbrs.kneighbors([query_vector])
# додати документи до запиту для надання контексту
history = []
for index in indices[0]:
history.append(flattened_df['chunks'].iloc[index])
# поєднати історію та введення користувача
history.append(user_input)
# створити об’єкт повідомлення
messages=[
{"role": "system", "content": "You are an AI assistant that helps with AI questions."},
{"role": "user", "content": "\n\n".join(history) }
]
# використати завершення чату для генерації відповіді
response = openai.chat.completions.create(
model="gpt-4",
temperature=0.7,
max_tokens=800,
messages=messages
)
return response.choices[0].message
chatbot(user_input)-
Якість відповідей — забезпечити природність, плавність і людяність
-
Закріпленість даних: оцінка, чи відповідь походить з наданих документів
-
Релевантність: оцінка відповідності та зв’язку відповіді із заданим питанням
-
Плавність — чи відповідає відповіді граматичним нормам
Існує багато різних сценаріїв, де виклики функцій можуть покращити ваш застосунок, такі як:
-
Питання та відповіді: закріплення даних вашої компанії у чаті, яким можуть користуватися співробітники для запитань.
-
Рекомендаційні системи: створення системи, що порівнює найближчі значення, наприклад, фільми, ресторани тощо.
-
Чатботи: збереження історії чату і персоналізація розмови на основі даних користувача.
-
Пошук зображень на основі векторних ембеддингів, корисний для розпізнавання зображень та виявлення аномалій.
Ми охопили основні аспекти RAG: починаючи від додавання даних у застосунок, користувацький запит і вивід. Для спрощення створення RAG ви можете використовувати фреймворки, такі як Semantic Kernel, Langchain або Autogen.
Для продовження вивчення Retrieval Augmented Generation (RAG) ви можете:
-
Побудувати фронтенд для застосунку, використовуючи обраний вами фреймворк
-
Використати фреймворк, такий як LangChain або Semantic Kernel, і відновити ваш застосунок.
Вітаємо з проходженням уроку 👏.
Після проходження уроку ознайомтесь з нашою Колекцією для навчання Генеративного ШІ, щоб продовжити вдосконалювати свої знання з Генеративного ШІ!
Відмова від відповідальності: Цей документ було перекладено за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ рідною мовою слід вважати авторитетним джерелом. Для критичної інформації рекомендується звернутися до професійного людського перекладу. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.


