English translation is not available yet. Showing Russian content.

RAG с мультиязычным поиском (русский/английский/китайский)

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: RAG с мультиязычным поиском (русский/английский/китайский)

1. Цель задачи

Разработать прототип RAG-системы (Retrieval-Augmented Generation), использующий мультиязычный эмбеддер BGE-M3 для индексации и поиска документов на русском, английском и китайском языках. Система должна принимать запросы на любом из трёх языков и возвращать релевантные документы из единого корпуса, содержащего документы на всех трёх языках. Ключевой результат значение метрики Recall@10 > 0.8 на каждом из трёх языков для тестового набора запросов.

2. Исходные данные

Что нужноОткуда взять
Модель эмбеддингов BGE-M3Hugging Face: BAAI/bge-m3 (размер ~2.2 ГБ)
Тестовый корпус документов (минимум 100 документов на каждый язык)Сгенерировать самостоятельно: 300 коротких текстов (100 русских, 100 английских, 100 китайских) по теме «наука и технологии»
Тестовые запросы (10 на каждый язык, всего 30)Составить вручную: каждый запрос должен иметь один релевантный документ в корпусе
Ground truth (соответствия запрос-документ)Определить при создании корпуса (запросы формулируются на основе содержания документа)
Индекс для быстрого поискаFAISS (Facebook AI Similarity Search) — библиотека для эффективного поиска по векторным базам

Если нет реального инструмента — симулируем:

  1. Для генерации корпуса документов напишите Python-скрипт, который создаёт 100 текстов на каждом языке с помощью шаблонов или случайного набора предложений (без использования LLM). Например, комбинируйте готовые фразы из технических статей.
  2. Тестовые запросы составляются вручную на основе первых 10 документов каждого языка. Для каждого запроса запишите ID релевантного документа в файл ground_truth.json.

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.10+Реализация пайплайна
Управление зависимостямиpip + requirements.txt или CondaВоспроизводимость среды
ЭмбеддингиHugging Face Transformers + BAAI/bge-m3Получение мультиязычных векторных представлений
Индексирование и поискFAISS (faiss-cpu или faiss-gpu)Эффективный косинусный/внутренний поиск по векторам
Обработка данныхPandas, NumPy, JSONПодготовка корпуса, запросов и ground truth
МетрикиScikit-learn, собственные функцииВычисление Recall@10
Среда разработкиJupyter Notebook или Python-скриптПрототипирование и фиксация результатов

4. Этапы выполнения

Этап 1: Подготовка данных и окружения (оценка времени: 1 час)

Действия

  1. Создайте виртуальное окружение и установите зависимости:
    pip install transformers torch faiss-cpu pandas numpy scikit-learn
    
  2. Загрузите модель BGE-M3:
    from transformers import AutoModel, AutoTokenizer
    model_name = "BAAI/bge-m3"
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModel.from_pretrained(model_name)
    model.eval()
    
  3. Сгенерируйте корпус документов (corpus.json):
    • Формат: список словарей {"id": int, "language": "ru"/"en"/"zh", "text": str}.
    • Для каждого языка создайте 100 текстов длиной 50–150 символов. Пример шаблона для русского:
      "Квантовый компьютер использует кубиты для параллельных вычислений."
      
    • Используйте комбинации тем: AI, космос, биотехнологии, физика.
  4. Составьте ground truth (ground_truth.json):
    • Выберите первые 10 документов каждого языка (id 0–9 для ru, 100–109 для en, 200–209 для zh).
    • Для каждого документа придумайте запрос на том же языке, однозначно на него указывающий. Сохраните в формате:
      [
        {"query": "запрос на русском", "relevant_doc_id": 0, "language": "ru"},
        ...
      ]
      

Ожидаемый результат этапа Файлы corpus.json (300 документов) и ground_truth.json (30 запросов). Загруженная модель BGE-M3.

Этап 2: Получение эмбеддингов для корпуса (оценка времени: 1 час)

Действия

  1. Напишите функцию encode_texts(texts, batch_size=32), которая:
    • Принимает список строк.
    • Токенизирует с параметром padding=True, truncation=True, max_length=512, return_tensors='pt'.
    • Пропускает через модель без градиентов, получает last_hidden_state, применяет mean pooling.
    • Возвращает массив numpy формы (n_texts, hidden_dim) – для BGE-M3 размерность 1024.
  2. Примените функцию ко всем текстам корпуса, сохраните матрицу corpus_embeddings.npy.
  3. Нормализуйте эмбеддинги (L2-норма) – это повысит качество косинусного поиска.

Ожидаемый результат этапа Матрица эмбеддингов corpus_embeddings.npy размером (300, 1024). Векторы нормализованы.

Этап 3: Индексирование и поиск (оценка времени: 0.5 часа)

Действия

  1. Создайте индекс FAISS типа IndexFlatIP (скалярное произведение) или IndexFlatL2.
    import faiss
    dim = 1024
    index = faiss.IndexFlatIP(dim)   # для косинусного расстояния с нормализованными векторами
    index.add(corpus_embeddings)
    
  2. Сохраните индекс на диск: faiss.write_index(index, "bge_m3_index.faiss").
  3. Реализуйте функцию search(query, k=10):
    • Переводит запрос в эмбеддинг через encode_texts([Вики/Query|query).
    • Ищет в индексе index.search(query_emb, k).
    • Возвращает id ближайших документов и расстояния.

Ожидаемый результат этапа Индекс bge_m3_index.faiss, функция поиска работает.

Этап 4: Оценка качества поиска (Recall@10) (оценка времени: 1 час)

Действия

  1. Для каждого запроса из ground_truth.json выполните поиск (k=10).
  2. Вычислите Recall@10 для каждого языка отдельно:
    def recall_at_k(retrieved_ids, relevant_id, k=10):
        return 1.0 if relevant_id in retrieved_ids[:k] else 0.0
    
  3. Усредните Recall@10 по всем запросам одного языка.
  4. Выведите отчёт:
    Recall@10 (Russian): 0.90
    Recall@10 (English): 0.85
    Recall@10 (Chinese): 0.95
    
  5. Если Recall@10 < 0.8 на каком-либо языке:
    • Проверьте качество запросов (не слишком ли общие).
    • Увеличьте корпус до 200 документов на язык.
    • Попробуйте добавить префикс инструкции: "Represent this sentence for searching relevant passages:" (для BGE-M3 рекомендуется).
    • Перезапустите этапы 2–4.

Ожидаемый результат этапа Значения Recall@10 для каждого языка, записанные в файл metrics.json.

Этап 5: Анализ и документирование (оценка времени: 0.5 часа)

Действия

  1. Оформите Jupyter Notebook с последовательным выполнением всех шагов.
  2. Добавьте в конец вывод метрик и примеры запросов с найденными документами.
  3. Зафиксируйте в README.md:
    • Краткое описание задачи.
    • Инструкцию по запуску.
    • Достигнутые метрики.
    • Наблюдения: как язык запроса влияет на поиск, какие ошибки возникли.

Ожидаемый результат этапа Notebook multilingual_rag.ipynb, файл README.md.

5. Критерии приемки (Definition of Done)

  • Реализован полный пайплайн: загрузка модели → эмбеддинги → индекс → поиск → метрики.
  • Recall@10 на русском языке ≥ 0.8.
  • Recall@10 на английском языке ≥ 0.8.
  • Recall@10 на китайском языке ≥ 0.8.
  • Код воспроизводим: все зависимости указаны в requirements.txt.
  • Корпус документов содержит не менее 100 уникальных текстов на каждый язык.
  • Ground truth включает 30 запросов (10 на язык) с правильными релевантными ID.
  • Индекс FAISS сохранён как двоичный файл и может быть переиспользован.
  • Результаты метрик выведены в консоль и сохранены в JSON.
  • Jupyter Notebook оформлен с пояснениями и выводами.

6. Ожидаемый результат

  1. Основной артефакт файл multilingual_rag.ipynb, содержащий:
    • Загрузку модели BGE-M3.
    • Генерацию корпуса документов (или загрузку из corpus.json).
    • Вычисление эмбеддингов.
    • Построение индекса FAISS.
    • Вычисление Recall@10 для всех трёх языков.
    • Вывод метрик и примеров.
  2. Вспомогательные файлы
    • corpus.json – корпус документов.
    • ground_truth.json – тестовые запросы с релевантными ID.
    • bge_m3_index.faiss – сериализованный индекс.
    • corpus_embeddings.npy – эмбеддинги корпуса (опционально).
    • metrics.json – метрики Recall@10 по языкам.
    • requirements.txt – список зависимостей.
  3. Дополнительно краткий отчёт в README.md с анализом сильных и слабых сторон мультиязычного поиска.

7. Возможные сложности и их решение

СложностьРешение
Модель BGE-M3 не загружается (проблемы с Hugging Face)Использовать зеркало hf-mirror.com или загрузить модель заранее вручную.
Эмбеддинги не нормализованы → низкое качество поискаПринудительно применить L2-нормализацию после mean pooling.
Китайские запросы не находят релевантные документыУбедиться, что китайские тексты токенизируются корректно (использовать китайские символы, а не пиньинь). Увеличить корпус до 200 документов.
Ошибка памяти при большом корпусеИспользовать faiss-gpu (если есть CUDA) или уменьшить batch_size.
Recall@10 ниже 0.8 на одном из языков1) Проверить ground truth: запрос должен быть точной парафразой части документа. 2) Добавить префикс инструкции BGE-M3: "Represent this sentence for searching relevant passages: " + query. 3) Увеличить k до 20 и проверить Recall@20.
Зависимости конфликтуют (torch + faiss)Создать conda environment с Python 3.10: conda create -n multilingual python=3.10 && conda install pytorch faiss-cpu.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Подготовка данных и окружения1 ч
Этап 2: Получение эмбеддингов1 ч
Этап 3: Индексирование и поиск0.5 ч
Этап 4: Оценка качества1 ч
Этап 5: Анализ и документирование0.5 ч
Итого4 ч

Примечание Для первого выполнения задачи заложите дополнительно 1 час на отладку и настройку модели (префиксы, batch_size). Оценка дана для выполнения на CPU с корпусом 300 документов. При использовании GPU время этапа 2 сокращается в 2–3 раза.

9. Связанные вопросы из базы знаний

ВопросТема
123Основы RAG: архитектура, компоненты
145Выбор эмбеддинговой модели для многоязычных текстов
267Метрики оценки поиска: Recall@k, MRR, NDCG
345Использование FAISS для векторного поиска
456Оптимизация batch-запросов к модели в Hugging Face
567Нормализация эмбеддингов и влияние на косинусное сходство
678Префиксы инструкций в модели BGE
789Сравнение BGE-M3, LaBSE и sentence-transformers
890Обработка китайского текста в NLP-пайплайне
901Тестирование RAG-систем: создание golden-датасета

10. Чек-лист самопроверки

  • Я создал виртуальное окружение и установил все зависимости из requirements.txt.
  • Я сгенерировал корпус из 300 документов (100 на каждый язык) и сохранил его в JSON.
  • Я составил 30 запросов (10 на каждый язык) с точным указанием релевантного документа.
  • Я загрузил модель BGE-M3 и получил эмбеддинги для всего корпуса.
  • Я построил индекс FAISS и выполнил поиск по всем тестовым запросам.
  • Я вычислил Recall@10 для каждого языка и убедился, что все значения ≥ 0.8.
  • Я оформил код в Jupyter Notebook с подробными комментариями и выводами.
  • Я проверил, что notebook воспроизводится с нуля (clean run).
  • Я написал README с описанием задачи, инструкцией и результатами.