Перейти к содержанию

Fine-tuning без галюцинаций

Чтобы обучить модель отвечать ТОЛЬКО на основе предоставленной документации и не выдумывать (не галлюцинировать), нужно применить комбинацию архитектурных, дата-инженерных и методологических подходов. Ниже — пошаговое руководство.


Основная идея: ограничить модель рамками документации

Модель по умолчанию — генеративная языковая модель: она учится предсказывать правдоподобный текст, а не "знать факты". Чтобы заставить её отвечать строго по документации, нужно:

  1. Обучить её распознавать, что ответ должен быть основан на документе.
  2. Научить говорить "Я не знаю", если информации в документации нет.
  3. Избегать смешивания с общими знаниями из предобучения.

Шаг 1: Подготовьте датасет в правильном формате

Используйте формат RAG-style (Retrieval-Augmented Generation) или closed-domain QA

Каждый пример должен включать: - Контекст — фрагмент вашей документации. - Вопрос — запрос, на который можно ответить только по этому контексту. - Ответ — точная выдержка или перефразированная цитата из документации. - (Опционально) Примеры вопросов без ответа → ответ: «Я не знаю» / «Это не указано в документации».

Пример 1 (есть ответ):

{
  "context": "LoRA (Low-Rank Adaptation) замораживает исходные веса модели и добавляет две маленькие обучаемые матрицы A и B.",
  "question": "Что делает LoRA с исходными весами модели?",
  "answer": "LoRA замораживает исходные веса модели."
}

Пример 2 (нет ответа):

{
  "context": "LoRA замораживает исходные веса модели и добавляет две маленькие обучаемые матрицы A и B.",
  "question": "Поддерживает ли LoRA квантование весов?",
  "answer": "Я не знаю. Эта информация отсутствует в предоставленной документации."
}

Важно: никогда не давайте модели отвечать на вопросы, выходящие за рамки контекста, даже если она "знает" ответ из предобучения.


Шаг 2: Используйте шаблон промпта, имитирующий RAG

Даже если вы не используете внешний ретривер, структура промпта должна выглядеть так:

### Документация:
{context}

### Вопрос:
{question}

### Ответ:
{answer}

Или в стиле Alpaca:

{
  "instruction": "Ответь на вопрос, используя ТОЛЬКО информацию из приведённой документации. Если ответ не содержится в документации, напиши: «Я не знаю».",
  "input": "Документация: {context}\n\nВопрос: {question}",
  "output": "{answer}"
}

Это учит модель игнорировать внутренние знания и смотреть только на контекст.


Шаг 3: Баланс данных

  • 80–90%: вопросы с ответами из документации.
  • 10–20%: вопросы без ответа → ответ "Я не знаю".

Это критически важно! Без таких примеров модель будет пытаться угадать даже при отсутствии информации.


Шаг 4: Обучение с LoRA (или полное)

  • Используйте LoRA для эффективности.
  • Целевые модули: q_proj, v_proj, gate_proj, up_proj, down_proj.
  • Рекомендуемые гиперпараметры:
  • r=64, alpha=128
  • dropout=0.1 (чтобы снизить переобучение на конкретные фразы)
  • learning_rate=2e-4
  • epochs=2–3
  • max_seq_length=2048 (или больше, если документы длинные)

Не используйте слишком много эпох — иначе модель начнёт запоминать ответы, а не учиться обобщать по контексту.


Шаг 5: Инференс — всегда подавайте контекст!

После обучения никогда не задавайте вопрос без контекста. Даже если вы используете WebUI:

### Документация:
LoRA замораживает исходные веса...

### Вопрос:
Что делает LoRA?

### Ответ:

Если вы спросите просто: "Что такое LoRA?" — модель может ответить из своих общих знаний, а не из вашей документации.

Это ключевой момент: модель не "помнит" документацию — она реагирует на контекст в промпте.


Альтернатива: RAG + базовая модель (без дообучения)

Если вы не хотите дообучать модель, можно использовать RAG-подход:

  1. Храните документацию в векторной БД (Chroma, FAISS).
  2. При вопросе — ищите релевантный фрагмент.
  3. Подавайте его в базовую LLM с промптом:
    "Ответь ТОЛЬКО по следующему тексту. Если информации нет — скажи 'Я не знаю'."

Плюсы:
- Не нужно обучать модель.
- Легко обновлять документацию.

Минусы:
- Зависит от качества ретривера.
- Может не сработать на сложных вопросах.


Чего НЕ делать

Ошибка Последствие
Обучать только на "голых" вопросах без контекста Модель будет отвечать из общих знаний
Не включать примеры "Я не знаю" Модель будет галлюцинировать на незнакомые темы
Использовать общий корпус + документацию без разделения Модель смешает доменные и общие знания
Слишком много эпох Переобучение → модель цитирует дословно, не умеет перефразировать

Итог: как добиться "ответов только по документации"

  1. Все обучающие примеры — в формате (контекст + вопрос → ответ).
  2. Включайте примеры с "Я не знаю".
  3. Используйте шаблон промпта, который явно ограничивает источник информации.
  4. На инференсе всегда подавайте релевантный фрагмент документации.
  5. Тестируйте на вопросах вне документации — модель должна отказываться отвечать.