Недавно вышли две новые модели Qwen — Qwen3-4B-Instruct-2507 и Qwen3-4B-Thinking-2507
Обе модели Qwen3 имеют хорошую длину контекста — 256 К, и, зная это, я подумал: «Почему бы не создать RAG, чтобы эффективно использовать длину контекста?». Стоит упомянуть, что семейство Qwen3 включает в себя множество моделей, предназначенных для кодирования, мышления, встраивания и переупорядочивания. Здесь, чтобы создать RAG наилучшим образом, мы будем использовать модель встраивания Qwen3 и модель переупорядочивания.
Не волнуйтесь, мы не начнём сразу с создания RAG! Сначала мы рассмотрим эти модели по отдельности, а затем создадим RAG.
Модели Qwen3: предыстория
Модели Qwen3 разработаны компанией Alibaba Cloud. Несколько моделей Qwen3 были выпущены несколько месяцев назад. В качестве улучшения этих моделей недавно были представлены две новые модели — Qwen3-Instruct-2507 и Qwen3-Thinking-2507 в трёх размерах: 235B-A22B, 30B-A3B и 4B. Обратите внимание, что в этой статье мы сосредоточимся в основном на варианте 4B модели Qwen3-Instruct-2507. Все эти модели имеют открытый исходный код и доступны на Hugging Face и Kaggle. Также стоит упомянуть, что модели Qwen3 поддерживают множество языков, а именно 119 языков и диалектов. Давайте посмотрим на несколько моделей Qwen3 в действии, а затем создадим RAG, для которого мы здесь собрались.
Демонстрация моделей Qwen3
Давайте начнём с модели генерации текста, но перед этим убедитесь, что у вас есть токен доступа к Hugging Face.
Примечание: мы будем проводить этот демонстрационный пример в Google Colab. После открытия нового ноутбука убедитесь, что добавили токен доступа как HF_TOKEN на вкладке secrets слева. Убедитесь, что доступ к ноутбуку включён.
Qwen3-4B-Instruct-2507
Это обновлённая версия модели Qwen3-4B без режима мышления и имеет значительную длину контекста — 256 К. Как видно из названия, эта модель имеет 4 миллиарда параметров, что относительно мало и подходит для использования в Colab. Давайте запустим эту модель с помощью Hugging Face transformers и посмотрим её в действии.
Примечание: измените тип среды выполнения на T4 GPU, чтобы справиться с моделью.
# Setup and Dependencies
import torch
import torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
# Instruct Model (Text Generation)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-4B-Instruct-2507")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-4B-Instruct-2507",
torch_dtype="auto",
device_map="auto"
)
prompt = "Объясните, что такое машинное обучение простыми словами."
messages = [{"role": "user", "content": prompt}]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=False
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(
**model_inputs,
max_new_tokens=256
)
output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist()
response = tokenizer.decode(output_ids, skip_special_tokens=True)
print(response)
Вот вывод, который я получил на свой вопрос о том, «Объясните, что такое машинное обучение простыми словами.»:
Конечно! В простых словах, машинное обучение — это способ для компьютеров учиться на данных и улучшать выполнение задач без явного программирования для этого.
Представьте, у вас есть робот, который учится распознавать кошек на фотографиях. Вместо того чтобы писать пошаговые инструкции типа «ищи круглое лицо, большие глаза и нос», вы просто показываете ему много фотографий кошек и собак. Со временем робот начинает понимать, что отличает кошку от собаки — он учится сам на примерах.
Это машинное обучение: компьютер смотрит на данные (например, фотографии, числа или текст), находит закономерности и становится лучше в принятии решений на основе этих закономерностей.
Подумайте об этом как о том, как ребёнок учится определять разных животных, видя их снова и снова. Машина делает что-то похожее — она учится на опыте (данных) и становится умнее со временем.
Короче говоря:
Машинное обучение = обучение компьютеров учиться на данных и совершенствоваться самостоятельно. 😊
Qwen3-Embedding-0.6B
Это модель встраивания, используемая для преобразования текста в плотные векторные представления для понимания отношений между текстами. Это важная часть RAG, которую мы будем создавать позже. Модель встраивания составляет основу Retriever в Retrieval Augmented Generation (RAG).
Давайте определим функцию для повторного использования и найдём встраивание, чтобы найти сходство между текстами. Я передаю 4 строки (текст) в списке «texts».
# Qwen3-Embedding-0.6B (Text Embeddings)
def last_token_pool(last_hidden_states, attention_mask):
left_padding = (attention_mask[:, -1].sum() == attention_mask.shape[0])
if left_padding:
return last_hidden_states[:, -1]
else:
sequence_lengths = attention_mask.sum(dim=1) - 1
batch_size = last_hidden_states.shape[0]
return last_hidden_states[torch.arange(batch_size, device=last_hidden_states.device), sequence_lengths]
tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen3-Embedding-0.6B', padding_side='left')
model = AutoModel.from_pretrained('Qwen/Qwen3-Embedding-0.6B')
texts = [
"Машинное обучение — это подмножество искусственного интеллекта.",
"Python — популярный язык программирования.",
"Сегодня солнечно.",
"Искусственный интеллект преобразует отрасли."
]
batch_dict = tokenizer(
texts,
padding=True,
truncation=True,
max_length=8192,
return_tensors="pt",
)
outputs = model(**batch_dict)
embeddings = last_token_pool(outputs.last_hidden_state, batch_dict['attention_mask'])
embeddings = F.normalize(embeddings, p=2, dim=1)
scores = (embeddings @ embeddings.T)
print(scores.tolist())
Вывод:
**[[1.0, 0.4834885597229004, 0.3609130382537842, 0.6805511713027954], [0.4834885597229004, 1.0000001192092896, 0.44289979338645935, 0.4494439363479614], [0.3609130382537842, 0.44289979338645935, 1.0000001192092896, 0.4508340656757355], [0.6805511713027954, 0.4494439363479614, 0.4508340656757355, 1.0]]**
Это матрица, которую мы рассчитали, найдя оценки сходства текстов друг с другом. Давайте просто посмотрим на первую строку матрицы для лучшего понимания. Как видите, сходство одинаковых текстов всегда равно 1, следующее сразу высокое — 0,68, что между предложением об ИИ и предложением о МЛ, а сходство между утверждением о погоде и ИИ не очень высокое, что имеет смысл.
Qwen3-Reranker-0.6B
Мы можем передать полученные фрагменты, которые могут быть получены с помощью векторного поиска с использованием модели встраивания. Модель переупорядочивания оценивает каждый фрагмент по отношению к запросу, чтобы упорядочить список документов и присвоить приоритет, или использовать эти оценки для подмножества полученных фрагментов. Мы увидим эту модель непосредственно в действии в следующем разделе для лучшего понимания.
Создание RAG с использованием моделей Qwen
Мы создадим RAG на блогах Analytics Vidhya (~ 40 блогов) с использованием трёх указанных моделей Qwen3. Мы будем последовательно обрабатывать данные и использовать модели. Для эффективной обработки мы будем загружать/выгружать модель для использования, чтобы сохранить память. Давайте рассмотрим шаги и погрузимся в скрипт.
- Шаг 1: Загрузите данные. Вот ссылка на мой репозиторий, где вы можете найти данные и скрипты.
- Шаг 2: Установите требования: !pip install faiss-cpu PyPDF2
- Шаг 3: Распакуйте данные в папку: !unzip Data.zip
- Шаг 4: Для упрощения выполнения вы можете просто добавить скрипт qwen_rag.py в среду Colab и запустить скрипт с помощью: !python qwen_rag.py
Разбивая скрипт:
- Мы используем библиотеку PYPDF2 для загрузки содержимого статей в формате PDF. Определена функция для чтения содержимого блога в форматах .txt или .pdf.
- Мы разбиваем содержимое на фрагменты размером 800 и перекрытием 100, чтобы сохранить релевантность контекста в последовательных документах.
- Мы используем FAISS для создания векторного хранилища и с помощью нашего запроса извлекаем топ-15 документов на основе сходства.
- Теперь мы используем реранкер на этих 15 документах, чтобы получить топ-3 с помощью этой функции:
def rerank_documents(query, candidates, k_rerank=3):
"""Rerank documents using reranker model"""
print("Reranking documents...")
tokenizer, model = load_reranker_model()
# Prepare inputs
pairs = []
for doc, _ in candidates:
pair = f"<Instruct>: Given a web search query, retrieve relevant passages that answer the query\n<Query>: {query}\n<Document>: {doc['content']}"
pairs.append(pair)
# Tokenize
inputs = tokenizer(pairs, padding=True, truncation=True, max_length=8192, return_tensors="pt").to(device)
# Get scores
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits[:, -1, :]
# Get yes/no token scores
token_false_id = tokenizer.convert_tokens_to_ids("no")
token_true_id = tokenizer.convert_tokens_to_ids("yes")
true_scores = logits[:, token_true_id]
false_scores = logits[:, token_false_id]
batch_scores = torch.stack([false_scores, true_scores], dim=1)
batch_scores = torch.nn.functional.log_softmax(batch_scores, dim=1)
scores = batch_scores[:, 1].exp().tolist()
# Unload reranker model
del tokenizer, model
clear_memory()
print("Reranker model unloaded")
# Sort by score
documents = [doc for doc, _ in candidates]
doc_scores = list(zip(documents, scores))
doc_scores.sort(key=lambda x: x[1], reverse=True)
return doc_scores[:k_rerank]
- Как только мы получим эти три верхних документа, мы передадим их в модель инструктирования, чтобы получить окончательный вывод от генератора с дополненной выборкой.
Вывод:
Question: В чём разница между LoRA и QLoRA?
Answer: LoRA (Low-Rank Adaptation) и QLoRA (Quantized Low-Rank Adaptation) — это обе техники тонкой настройки с низким рангом параметров, используемые для адаптации больших языковых моделей (LLMs) к конкретным задачам. Хотя они имеют общие черты, они различаются по своему подходу и эффективности.
1. LoRA (Low-Rank Adaptation):
- LoRA вводит низкоранговые матрицы (A и B) в модуль самовнимания каждого слоя в предварительно обученной модели. Эти матрицы действуют как адаптеры, которые позволяют модели адаптироваться и специализироваться для конкретных задач, минимизируя при этом количество необходимых дополнительных параметров.
- LoRA снижает накладные расходы на параметры, фокусируясь на оптимизации обучаемых низкоранговых матриц вместо тонкой настройки всех параметров. Это делает его гораздо более экономичным по памяти и вычислительно дешёвым.
- LoRA позволяет предварительно обученной модели использоваться для нескольких задач, облегчая эффективное переключение задач во время развёртывания.
- LoRA не вносит дополнительной задержки при выводе по сравнению с полностью настроенными моделями, что делает его пригодным для приложений реального времени.
2. QLoRA (Quantized Low-Rank Adaptation):
- QLoRA — это расширение LoRA, которое дополнительно вводит квантование для повышения эффективности параметров во время тонкой настройки. Он основан на принципах LoRA, вводя 4-битное квантование NormalFloat (NF4) и методы двойного квантования.
- NF4 квантование использует внутреннее распределение предварительно обученных нейронных сетей, преобразуя все веса в фиксированное распределение, которое помещается в диапазон NF4 (-1 до 1). Это позволяет эффективно квантовать без необходимости дорогостоящих алгоритмов оценки квантилей.
- Двойное квантование решает проблему накладных расходов памяти квантования констант, квантуя сами константы квантования. Это значительно снижает объём памяти без ущерба для производительности.
- QLoRA достигает ещё более высокой эффективности использования памяти за счёт введения квантования, что делает его более подходящим для развёртывания на устройствах с ограниченными вычислительными ресурсами.
- Несмотря на свою параметрическую эффективность, QLoRA сохраняет высокое качество модели, работая наравне или даже лучше, чем полностью настроенные модели в различных последующих задачах.
Вкратце, в то время как LoRA фокусируется на сокращении количества обучаемых параметров за счёт низкоранговой адаптации, QLoRA дополнительно повышает эту эффективность за счёт внедрения методов квантования, что делает его более подходящим для развёртывания на устройствах с ограниченными вычислительными ресурсами.
Источники: fine_tuning.txt, Parameter-Efficient Fine-Tuning of Large Language Models with LoRA and QLoRA.pdf, Parameter-Efficient Fine-Tuning of Large Language Models with LoRA and QLoRA.pdf
Примечание: вы можете обратиться к файлу журнала «rag_retrieval_log.txt», чтобы получить более подробную информацию о документах, извлечённых и оценённых по сходству с запросом и оценках реранкера.
Заключение
Объединив модели инструктирования, встраивания и реранкера Qwen3, мы создали практичный конвейер RAG, который максимально использует их сильные стороны. С длиной контекста 256 К и поддержкой множества языков семейство Qwen доказывает свою универсальность для реальных задач. Следующие шаги могут включать в себя попытку увеличения количества документов, передаваемых модели инструктирования, или использование модели мышления для другого варианта использования. Выходы также кажутся многообещающими. Я предлагаю вам попробовать оценить RAG по таким метрикам, как достоверность и релевантность ответов, чтобы убедиться, что LLM в основном свободна от галлюцинаций в вашей задаче/варианте использования.
Часто задаваемые вопросы
Что такое chunking?
Chunking — это процесс разбиения большого текста на более мелкие перекрывающиеся сегменты для сохранения контекста при обеспечении эффективного извлечения.
Что такое векторное хранилище?
Векторное хранилище — это база данных, в которой хранятся текстовые вложения для быстрого поиска сходства и извлечения.
Как я могу оценить RAG?
Вы можете оценить RAG, используя такие показатели, как точность, релевантность и согласованность ответов по разным запросам.
Как выбрать, сколько документов передать в LLM?
Это зависит от вашего ограничения длины контекста; обычно 3–5 документов с наивысшим рейтингом работают хорошо.
Что такое реранкер?
Реранкер оценивает извлечённые документы по отношению к запросу, чтобы переупорядочить их по релевантности перед передачей в LLM.
