Fine-tuning без галюцинаций
Чтобы обучить модель отвечать ТОЛЬКО на основе предоставленной документации и не выдумывать (не галлюцинировать), нужно применить комбинацию архитектурных, дата-инженерных и методологических подходов. Ниже — пошаговое руководство.
Основная идея: ограничить модель рамками документации¶
Модель по умолчанию — генеративная языковая модель: она учится предсказывать правдоподобный текст, а не "знать факты". Чтобы заставить её отвечать строго по документации, нужно:
- Обучить её распознавать, что ответ должен быть основан на документе.
- Научить говорить "Я не знаю", если информации в документации нет.
- Избегать смешивания с общими знаниями из предобучения.
Шаг 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=128dropout=0.1(чтобы снизить переобучение на конкретные фразы)learning_rate=2e-4epochs=2–3max_seq_length=2048(или больше, если документы длинные)
Не используйте слишком много эпох — иначе модель начнёт запоминать ответы, а не учиться обобщать по контексту.
Шаг 5: Инференс — всегда подавайте контекст!¶
После обучения никогда не задавайте вопрос без контекста. Даже если вы используете WebUI:
### Документация:
LoRA замораживает исходные веса...
### Вопрос:
Что делает LoRA?
### Ответ:
Если вы спросите просто: "Что такое LoRA?" — модель может ответить из своих общих знаний, а не из вашей документации.
Это ключевой момент: модель не "помнит" документацию — она реагирует на контекст в промпте.
Альтернатива: RAG + базовая модель (без дообучения)¶
Если вы не хотите дообучать модель, можно использовать RAG-подход:
- Храните документацию в векторной БД (Chroma, FAISS).
- При вопросе — ищите релевантный фрагмент.
- Подавайте его в базовую LLM с промптом:
"Ответь ТОЛЬКО по следующему тексту. Если информации нет — скажи 'Я не знаю'."
Плюсы:
- Не нужно обучать модель.
- Легко обновлять документацию.
Минусы:
- Зависит от качества ретривера.
- Может не сработать на сложных вопросах.
Чего НЕ делать¶
| Ошибка | Последствие |
|---|---|
| Обучать только на "голых" вопросах без контекста | Модель будет отвечать из общих знаний |
| Не включать примеры "Я не знаю" | Модель будет галлюцинировать на незнакомые темы |
| Использовать общий корпус + документацию без разделения | Модель смешает доменные и общие знания |
| Слишком много эпох | Переобучение → модель цитирует дословно, не умеет перефразировать |
Итог: как добиться "ответов только по документации"¶
- Все обучающие примеры — в формате (контекст + вопрос → ответ).
- Включайте примеры с "Я не знаю".
- Используйте шаблон промпта, который явно ограничивает источник информации.
- На инференсе всегда подавайте релевантный фрагмент документации.
- Тестируйте на вопросах вне документации — модель должна отказываться отвечать.