Дообучение LLM методом Instruction Tuning
Instruction Tuning — метод дообучения языковой модели на наборе пар «инструкция → ответ», обучающий модель следовать текстовым инструкциям на естественном языке. Именно этот шаг превращает base LLM (предобученную на предсказание следующего токена) в Instruct-модель, способную выполнять задания. Большинство публичных Instruct-моделей (Llama Instruct, Mistral Instruct, Qwen Instruct) получены именно этим способом.
Base vs Instruct: принципиальная разница
Base LLM (Llama 3.1 8B): продолжает текст. Дайте ей начало предложения — она его продолжит, но не ответит на вопрос как ассистент.
Instruct LLM (Llama 3.1 8B Instruct): следует инструкциям. Умеет отвечать на вопросы, выполнять задачи, отказываться от вредного контента.
При дообучении корпоративной модели мы обычно берём уже готовую Instruct-версию и адаптируем под домен. Но иногда нужно провести полноценный Instruction Tuning с нуля — например, при работе с base-моделью или при необходимости переопределить базовое поведение.
Форматы Instruction Tuning
Alpaca-формат (простой):
{
"instruction": "Переведи текст с английского на русский",
"input": "The contract must be signed before the deadline",
"output": "Договор должен быть подписан до истечения срока"
}
ShareGPT-формат (многоходовый диалог):
{
"conversations": [
{"from": "human", "value": "Проанализируй баланс компании"},
{"from": "gpt", "value": "Для анализа баланса нужны следующие показатели..."},
{"from": "human", "value": "Как интерпретировать соотношение активов?"},
{"from": "gpt", "value": "Соотношение текущих и долгосрочных активов показывает..."}
]
}
Chat Template-формат (современный стандарт):
# Пример для Llama 3 chat template
messages = [
{"role": "system", "content": "Ты — ассистент по финансовому анализу"},
{"role": "user", "content": "Рассчитай ROE"},
{"role": "assistant", "content": "ROE = Чистая прибыль / Собственный капитал × 100%..."},
]
# Применение chat template
formatted = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
Объём данных для Instruction Tuning
Исследование LIMA (Less is More for Alignment, 2023) показало: 1000 высококачественных примеров дают конкурентоспособное качество по сравнению с 52000 примерами в Alpaca. Качество важнее количества.
Ориентиры для специализированного Instruction Tuning:
| Задача | Минимальный объём | Оптимальный объём |
|---|---|---|
| Специализация стиля | 100–300 | 500–1000 |
| Новый домен (среднесложный) | 500–1000 | 2000–5000 |
| Сложный технический домен | 1000–2000 | 5000–15000 |
| Смена базового поведения | 2000–5000 | 10000–50000 |
Instruction Tuning для корпоративного ассистента
Задача: дообучить Llama 3.1 8B на стандарты корпоративной коммуникации IT-компании — официальный тон, использование принятых сокращений и терминологии, структура ответов по шаблонам.
Датасет: 1800 примеров — реальные внутренние переписки, преобразованные в пары инструкция/ответ.
Особенность: датасет включает negative examples — примеры, которые модель должна научиться отклонять (запросы на конкурентов, персональные данные сотрудников).
from trl import SFTTrainer, SFTConfig
from peft import LoraConfig
trainer = SFTTrainer(
model=model,
args=SFTConfig(
output_dir="./corporate-instruct",
num_train_epochs=4,
learning_rate=2e-4,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
max_seq_length=2048,
bf16=True,
# Маскируем промпт при loss-вычислении — обучаем только на completion
dataset_text_field="text",
),
train_dataset=formatted_dataset,
peft_config=LoraConfig(r=16, lora_alpha=32, target_modules=["q_proj","v_proj"]),
)
Важно: при Instruction Tuning стандартная практика — маскировать instruction часть при вычислении loss (учитываем loss только на response токенах). В TRL это контролируется через DataCollatorForCompletionOnlyLM.
Результаты:
- Adherence to corporate tone (LLM-judge, 1–5): 2.9 → 4.4
- Correct use of domain terminology: 61% → 87%
- Appropriate refusals: 34% → 89%
- Unwanted refusals (ложные отказы): 8% → 2%
Сборка instruction dataset из неразмеченных документов
# Pipeline: документ → instruction examples
def document_to_instructions(doc_text: str, llm_client) -> list:
"""Конвертирует корпоративный документ в обучающие примеры"""
response = llm_client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"""Из следующего документа создай 10 обучающих примеров для LLM.
Каждый пример: {{"instruction": "задание", "output": "правильный ответ на основе документа"}}.
Разнообразь типы заданий: вопросы, суммаризация, анализ, сравнение.
Документ:
{doc_text[:3000]}
Верни JSON-массив примеров."""
}],
)
return json.loads(response.choices[0].message.content)
Сроки
- Проектирование датасета и сбор источников: 2–3 недели
- Генерация и верификация примеров: 2–4 недели
- Обучение и итерации: 1–2 недели
- Итого: 5–9 недель







