Когда большие модели слишком дороги, а маленькие — слишком тупые
Claude 4.5 Opus генерирует SQL лучше любого джуна. Но каждый запрос стоит денег. Много денег. Особенно когда нужно обрабатывать тысячи запросов в день.
Вот классическая дилемма: большие модели (70B+) работают на уровне эксперта, но требуют GPU за $10k+. Малые модели (1B-) дешевые, но часто бесплатные, но их ответы — это лотерея. Особенно в Text2SQL, где ошибка в JOIN может сломать всю аналитику.
Типичная ошибка: пытаться обучать маленькую модель на публичных датасетах вроде Spider. Эти данные слишком общие. Ваша модель научится писать SQL для ресторанов и библиотек, но проигнорирует специфику вашей БД с кастомными полями и бизнес-логикой.
Решение: дистилляция через разговор
Вместо месяцев сбора данных и недель обучения — один диалог с Claude. Суть в том, чтобы заставить большую модель генерировать не просто ответы, а обучающие примеры для маленькой. С объяснениями. С нюансами. С типичными ошибками.
Ключевая идея: Claude становится не просто ассистентом, а инструктором. Он создает синтетический датасет, который идеально подходит для вашей задачи. И делает это за час.
Что понадобится
- API ключ Anthropic (не бесплатный, нужен доступ к Claude 4.5)
- Сервер с GPU (минимум 16GB VRAM — хватит для обучения 0.6B)
- Схема вашей базы данных (таблицы, поля, типы, связи)
- Примеры типичных бизнес-вопросов (10-20 штук)
Если думаете, что можно обойтись без схемы БД — забудьте. Claude должен понимать контекст. Без схемы он будет генерировать SQL для воображаемых таблиц. А ваша модель потом будет пытаться делать SELECT из несуществующего поля revenue_2025.
Шаг 0: Установка инструментов
# Всё в одном месте, чтобы не бегать по репозиториям
pip install anthropic transformers datasets peft torch accelerate
pip install sqlparse pandas sqlalchemy
Еще нужен distil-cli — утилита для автоматизации дистилляции. Её нет в PyPI, но есть на GitHub.
git clone https://github.com/distil-ai/distil-cli
cd distil-cli
pip install -e .
Внимание: оригинальный distil-cli мог не обновляться с 2024 года. Проверьте, есть ли форки с поддержкой Claude 4.5 API. Если нет — придется адаптировать код под новые эндпоинты Anthropic.
1 Генерируем промпт для Claude
Не просто "сгенерируй датасет". Нужен структурированный запрос, который заставит Claude работать как опытный тренер.
prompt_template = """
Ты — эксперт по SQL и дистилляции знаний.
Моя задача: обучить маленькую языковую модель (0.6B параметров) преобразовывать естественный язык в SQL.
Схема базы данных:
{schema}
Типичные вопросы пользователей:
{questions}
Сгенерируй обучающий датасет из 1000 примеров. Каждый пример должен содержать:
1. Структура:
- {id}: {int}
- {question}: {str}
- {answer}: {str}
- {explanation}: {str}
- {sql}: {str}
- {table_name}: {str}
- {column_name}: {str}
- {pivot}: {str}
- {join}: {str}
- {where}: {str}
- {order_by}: {str}
- {limit}: {str}
2. Пример:
- question: "Сколько пользователей зарегистрировалось в прошлом месяце?"
- answer: "В прошлом месяце зарегистрировалось 1 234 пользователя."
- explanation: "Используем таблицу users, фильтруем по полю registration_date за последние 30 дней, применяем COUNT."
- sql: "SELECT COUNT(*) FROM users WHERE registration_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)"
3. Важные моменты:
- Включай сложные случаи: JOIN 3+ таблиц, подзапросы, оконные функции
- Добавь 10% примеров с намеренными ошибками (и объясни, почему это ошибка)
- Разнообразь формулировки вопросов (синонимы, разный порядок слов)
- Используй только схему выше, не выдумывай поля
Верни JSON-массив с примерами.
"""
Почему такой подробный промпт? Потому что Claude 4.5 понимает структурированные запросы. Если дать просто "сгенерируй датасет", получится мешанина. А так — каждый пример будет содержать метаданные для обучения.
2 Запускаем генерацию через API
Не через веб-интерфейс. Там ограничение на длину ответа. Нужно API.
import anthropic
import json
client = anthropic.Anthropic(api_key="your_key_here")
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4000,
temperature=0.7,
system="Ты генерируешь качественный обучающий датасет для Text2SQL модели.",
messages=[
{
"role": "user",
"content": prompt_template.format(schema=db_schema, questions=example_questions)
}
]
)
# Claude 4.5 иногда возвращает JSON в текстовом виде, нужно парсить
try:
dataset = json.loads(response.content[0].text)
except json.JSONDecodeError:
# Если не JSON, ищем массив в тексте
import re
json_match = re.search(r'\[.*\]', response.content[0].text, re.DOTALL)
if json_match:
dataset = json.loads(json_match.group())
Температуру ставим 0.7, а не 0.1. Нужно разнообразие в вопросах. Если поставить низкую температуру, Claude начнет генерировать шаблонные примеры. Модель потом научится только на шаблонах.
Стоимость? Около $15-20 за 1000 примеров. Дешевле, чем нанимать аннотаторов. Быстрее, чем собирать данные вручную.
3 Подготовка данных для обучения
Claude сгенерировал JSON. Но модели нужен особый формат. Особенно если используете QLoRA или другой метод эффективной настройки.
from datasets import Dataset
import pandas as pd
# Преобразуем в формат для Hugging Face
df = pd.DataFrame(dataset)
# Создаем тексты для обучения
def format_example(row):
return f"""Schema: {db_schema}\nQuestion: {row['question']}\nSQL: {row['sql']}"""
df['text'] = df.apply(format_example, axis=1)
# Сохраняем
hf_dataset = Dataset.from_pandas(df[['text']])
hf_dataset.save_to_disk('./text2sql_dataset')
Зачем сохранять только текст? Потому что для дистилляции знаний нужно учить модель на парах "вопрос-ответ". Объяснения и метаданные — это для контроля качества, а не для обучения.
4 Выбор базовой модели
Тут есть нюанс. Можно взять готовую Text2SQL модель и дообучить. А можно взять общую языковую модель и научить её с нуля.
| Модель | Параметры | Плюсы | Минусы |
|---|---|---|---|
| DeepSeek-Coder-V3-Lite | 1.3B | Уже умеет код, есть понимание SQL | Чуть больше нужного размера |
| Qwen2.5-Coder-1.5B | 1.5B | Хорошая поддержка китайского и английского | Не всегда стабильна в генерации SQL |
| Phi-4 | 4B | Отличное качество при маленьком размере | Требует больше памяти |
Мой выбор на 21.01.2026 — DeepSeek-Coder-V3-Lite. Почему? Потому что DeepSeek-V3 (полная версия) показала лучшие результаты в наших тестах Text2SQL для CSV, а Lite-версия сохраняет 80% качества при вдвое меньшем размере.
Если нужно именно 0.6B — придется либо квантовать 1.3B модель, либо искать специализированные модели. Но честно? Разница в потреблении памяти между 0.6B и 1.3B всего 2.5GB против 5GB. Стоит ли овчинка выделки?
5 Обучение с QLoRA
Полное обучение 1.3B модели требует 16GB VRAM. QLoRA снижает требования до 8-10GB.
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from trl import SFTTrainer
from peft import LoraConfig
import torch
model_name = "deepseek-ai/deepseek-coder-1.3b"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# Конфигурация LoRA
peft_config = LoraConfig(
r=16, # rank
lora_alpha=32,
lora_dropout=0.1,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
bias="none",
task_type="CAUSAL_LM"
)
# Аргументы обучения
training_args = TrainingArguments(
output_dir="./text2sql-model",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
warmup_steps=100,
logging_steps=10,
save_strategy="epoch",
learning_rate=2e-4,
fp16=True,
optim="paged_adamw_8bit",
report_to="none"
)
# Тренер
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=hf_dataset,
peft_config=peft_config,
dataset_text_field="text",
max_seq_length=512,
tokenizer=tokenizer
)
# Запуск
trainer.train()
3 эпохи — это много? Для синтетического датасета из 1000 примеров — в самый раз. Модель успевает выучить паттерны, но не переобучается.
Проверка качества: как не обмануть себя
Самая опасная часть дистилляции — это когда модель учится на своих же ошибках. Claude генерирует 1000 примеров. 10% из них — намеренные ошибки. Но что если Claude ошибся в других 20%?
План проверки:
- Выбрать случайные 50 примеров из датасета
- Вручную проверить SQL на корректность (можно через EXPLAIN в тестовой БД)
- Запустить модель на этих же вопросах, сравнить ответы с эталоном от Claude
- Измерить точность match (точное совпадение SQL) и execution accuracy (результат выполнения)
Если точность ниже 70% — что-то пошло не так. Либо плохой промпт, либо мало данных, либо модель не подходит.
Не используйте автоматические метрики вроде BLEU для оценки SQL. Они бесполезны. SELECT COUNT(*) и SELECT COUNT(id) дают одинаковый результат, но BLEU посчитает их разными. Лучше выполнять SQL на тестовой базе и сравнивать результаты.
Почему это работает, когда классическая дистилляция проваливается
Обычная дистилляция берет большие датасеты (типа Spider) и пытается научить маленькую модель общим паттернам. Проблема в том, что Spider содержит SQL для 200 разных схем. Модель учится "среднему по больнице" SQL.
Наш подход — это дистилляция знаний, заточенная под конкретную схему. Claude понимает именно ваши таблицы, ваши поля, ваши бизнес-правила. И генерирует примеры, которые релевантны на 100%.
Это как разница между общим курсом английского и занятиями с репетитором, который готовит вас к конкретному собеседованию в конкретную компанию.
Ограничения и подводные камни
- Стоимость API: $20 за датасет — это если все пойдет хорошо. Если придется перегенерировать — цена удваивается
- Качество схемы: Если в схеме БД есть ошибки (устаревшие поля, неверные типы), Claude нагенерирует некорректные примеры
- Специфичные диалекты SQL: PostgreSQL != MySQL != SQLite. Нужно явно указывать диалект в промпте
- Контекстное окно Claude: 200k токенов звучит много, но сложная схема БД может занять половину
Самое неприятное ограничение: этот метод не работает для задач, где нужны глубокие рассуждения. Если ваш SQL требует понимания бизнес-логики вроде "вычислить LTV клиента с учетом сезонности", маленькая модель не справится. Тут нужны либо цепочки мыслей, либо дистилляция рассуждений в Mamba.
Альтернативы: когда Claude — не вариант
Нет API ключа? Бюджет нулевой? Есть варианты:
- Использовать GPT-4o mini через Azure — в 3 раза дешевле Claude
- Сгенерировать 100 примеров вручную, а потом использовать DistilBERT для аугментации
- Взять готовую модель типа SQLCoder-7B и дообучить на своих данных
Но честно? Если денег нет совсем, лучше начать с готовых образовательных моделей и адаптировать их. Чем пытаться дистиллировать без бюджета.
Что дальше? Модель обучена, что с ней делать
Обученная 0.6B модель потребляет 2-3GB памяти. Её можно:
- Запустить на CPU через llama.cpp — 4-5 секунд на запрос
- Добавить в RAG-систему для автоматической аналитики
- Интегрировать в BI-инструменты как плагин
- Использовать для предварительной валидации SQL перед выполнением
Главное — не забыть про мониторинг. Маленькие модели иногда галлюцинируют. Нужно отслеживать процент некорректных SQL и переобучать на новых данных.
И последний совет: сохраните промпт, который вы использовали для Claude. Через полгода, когда схема БД изменится, вам нужно будет просто обновить схему в промпте и запустить генерацию заново. Обучение с нуля займет еще 3 часа. И это всё.
Дистилляция через разговор — это не магия. Это просто эффективное использование того, что большие модели умеют объяснять. А маленькие — умеют учиться. Главное — правильно их познакомить.