Дофіно-tuning LLM методом Instruction Tuning
Instruction Tuning — метод дофіно-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): слідує інструкціям. Вміє відповідати на запитання, виконувати задачі, відхиляти шкідливий контент.
При дофіно-tuning корпоративної моделі ми зазвичай беремо вже готову 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 для корпоративного асистента
Завдання: дофіно-tune 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 датасету з розмічених документів
# 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 тижнів







