LLM: fine-tuning, RAG, агенты и production-деплой
Модель GPT-4 или Claude 3.5 Sonnet через API — это не решение задачи, это инструмент. Когда приходит требование «сделай как ChatGPT, но на наших данных», за этим скрывается целый спектр реальных задач: от настройки промптов до обучения собственной модели весом 70B параметров. Где именно находится ваша задача — зависит от данных, latency-требований, бюджета и того, насколько критична конфиденциальность.
Разберём каждый слой стека по отдельности.
RAG: где чаще всего ломается и почему
RAG (Retrieval-Augmented Generation) — архитектурно простая идея: ищем релевантные документы, кладём в контекст, модель отвечает. На практике ломается в нескольких местах.
Chunking без перекрытия. Классическая ошибка: chunk_size=512, overlap=0. Если ответ на вопрос лежит на границе двух чанков, retrieval не найдёт ни один из них с достаточной уверенностью. Решение: overlap 15-25% от chunk_size, плюс рассмотреть sentence-aware splitting через spaCy или NLTK вместо наивного разбиения по символам.
Плохой embedding-моделью. text-embedding-ada-002 — хороший общий embedder, но на юридических или медицинских текстах проигрывает специализированным моделям. E5-large-v2, BGE-M3, или fine-tuned sentence-transformers на доменных данных дают значительно лучшее качество recall@k. Разница может быть 15-25% по Recall@5.
Отсутствие re-ranking. Векторный поиск оптимизирован по скорости, не по релевантности. Cross-encoder re-ranking (ms-marco-MiniLM-L-6-v2, bge-reranker-large) после первичного retrieval значительно улучшает точность топ-3 результатов при приемлемой latency (+50-150ms). Это часто важнее улучшения embedding-модели.
Гибридный поиск. Только dense vectors плохо работают на точных запросах: имена, артикулы, коды. BM25 (sparse) хорошо находит точные совпадения, плохо понимает семантику. Гибрид через RRF (Reciprocal Rank Fusion) — оптимальный компромисс. Qdrant, Weaviate и pgvector 0.7+ поддерживают гибридный поиск нативно.
Типичная production-архитектура RAG-системы для корпоративного knowledge base: документы → preprocessing (PyMuPDF, Unstructured) → chunking → embedding (BGE-M3) → Qdrant → гибридный поиск → cross-encoder re-ranking → контекст → LLM (vLLM или OpenAI API) → ответ с источниками.
Fine-tuning: когда промпт-инжиниринг уже не помогает
Промпт-инжиниринг решает 70% задач адаптации LLM под домен. Остальные 30% требуют fine-tuning. Признаки того, что без него не обойтись: модель игнорирует специфический формат вывода даже при детальном описании в промпте; задача требует глубокого знания специализированной лексики (медицина, право, техника); нужно значительно снизить затраты на токены, заменив большую модель меньшей специализированной.
LoRA и QLoRA — стандарт для supervised fine-tuning. LoRA добавляет trainable low-rank матрицы к attention-слоям, не изменяя основные веса. Типичная конфигурация для Llama-3 8B: r=64, lora_alpha=128, target_modules=["q_proj", "v_proj", "k_proj", "o_proj"]. Trainable параметров ~0.8% от 8B — обучение укладывается на одну A100 40GB.
QLoRA добавляет 4-битную квантизацию базовой модели: загружаем в NF4 через bitsandbytes, обучаем только LoRA-адаптеры в bf16. Это позволяет fine-tune 70B модели на двух A100 40GB, хотя скорость обучения падает примерно вдвое по сравнению с полным bf16.
DPO вместо RLHF. Direct Preference Optimization — более простая альтернатива RLHF для alignment под стиль или предпочтения. Нужны пары (chosen, rejected) вместо скалярных reward-сигналов. trl (Transformer Reinforcement Learning) от Hugging Face имеет готовый DPOTrainer — реализация занимает десятки строк кода.
Типичная ошибка при fine-tuning. Датасет из 500 примеров, обучение 5 эпох, validation loss 0.8 — кажется норм. Но на тесте модель деградировала на общих инструкциях. Причина: catastrophic forgetting. Решение — добавить в обучающую выборку 10-20% общих instruction-following примеров (например, из Alpaca или FLAN), чтобы не разрушить исходные возможности модели.
Prompt engineering и structured outputs
Промпт-инжиниринг — это не «напиши хороший промпт». Это систематическая работа с форматом, few-shot примерами, chain-of-thought и управлением контекстом.
Для задач, требующих структурированного вывода (JSON, извлечение сущностей, классификация), используем function calling / tool use (OpenAI, Claude, Mistral) или constrained generation через Outlines или Guidance. Это даёт гарантированный формат вывода без постобработки regex.
Structured outputs через response_format={"type": "json_schema", ...} в OpenAI API — самый надёжный способ для production, где downstream-система ожидает конкретную схему.
Оценка промптов — отдельная задача. Строим eval-датасеты из 50-200 реальных примеров с ground truth, прогоняем автоматические метрики (ROUGE, BERTScore для открытых ответов; accuracy для классификации) плюс LLM-as-judge для качественной оценки.
Мультиагентные системы
Агенты — LLM с доступом к инструментам (tools): поиск в интернете, выполнение кода, запросы к API, работа с базами данных. Ключевые паттерны:
ReAct (Reason + Act). Модель рассуждает → выбирает инструмент → наблюдает результат → рассуждает снова. LangChain и LlamaIndex реализуют этот паттерн из коробки. Для production рекомендуем добавлять timeout на инструменты и максимальное число шагов.
Multi-agent orchestration. Несколько специализированных агентов с coordinator-агентом сверху. Например: coordinator → researcher (поиск + summarization) + coder (генерация и выполнение кода) + critic (проверка). AutoGen (Microsoft), CrewAI, или кастомная реализация на LangGraph.
Практический стоп. Агентные системы недетерминированы. В продакшене это означает: нужны обязательные guardrails (валидация вывода, лимиты на количество шагов и стоимость), логирование каждого шага, возможность human-in-the-loop для критических действий.
vLLM и production-деплой LLM
Если задача — serving собственной или open-source модели под нагрузкой, vLLM — первый выбор.
PagedAttention. Ключевое innovation vLLM: KV-cache управляется как virtual memory в OS, без фрагментации. Это позволяет обрабатывать параллельные запросы с разной длиной контекста без лишних копирований памяти. Результат: throughput в 2-4x выше по сравнению с наивным HuggingFace Transformers inference.
Continuous batching. Запросы добавляются в батч по мере поступления, а не ждут формирования полного батча. Снижает latency при неравномерной нагрузке.
Типичные числа на A100 80GB для Llama-3 8B (bf16): 400-600 req/s (output tokens/s), P50 latency 200-400ms, P99 latency 600-900ms при concurrency 64. Для 70B на двух A100 80GB с tensor parallelism: 80-120 req/s, P99 latency 1.5-2.5s.
Квантизация через AWQ или GPTQ снижает потребление памяти в 2x при деградации качества в пределах 1-3% на большинстве benchmarks. На A10G (24GB) это часть позволяет запустить 13B модель там, где без квантизации помещается только 7B.
Мониторинг деплоя. Логируем: latency (P50/P95/P99), throughput (tokens/s), queue depth, cache hit rate. Grafana + Prometheus — стандарт. vLLM экспортирует метрики нативно в формате Prometheus.
Выбор базовой модели
| Модель | Параметры | Сильные стороны | Контекст |
|---|---|---|---|
| Llama-3.1 8B | 8B | Баланс качество/скорость | 128k |
| Llama-3.1 70B | 70B | Сложные рассуждения | 128k |
| Mistral 7B / Mixtral 8x7B | 7B / 47B | Эффективность на размер | 32k |
| Qwen2.5 72B | 72B | Код, мультиязычность | 128k |
| Gemma 2 27B | 27B | Открытая лицензия | 8k |
Для большинства задач fine-tuning 8B модели достаточно. 70B нужен когда задача требует глубокого рассуждения или baseline 8B не достигает нужного качества даже после дообучения.
Этапы работы над LLM-проектом
Аудит задачи. Формализуем что именно модель должна делать, собираем eval-датасет из 100+ реальных примеров. Без eval нельзя измерить прогресс.
Baseline через промпт-инжиниринг. Тестируем OpenAI/Anthropic API с хорошо настроенным системным промптом. Часто этого достаточно. Если нет — видим конкретный gap и понимаем, что нужно менять.
RAG или fine-tuning. Если проблема в знаниях о конкретных документах — RAG. Если проблема в стиле, формате, специфической лексике — fine-tuning. Часто нужно и то, и другое.
Обучение и валидация. Готовим датасет, запускаем обучение с трекингом в W&B, оцениваем на holdout-сете и на реальных пользовательских запросах.
Деплой и мониторинг. vLLM на собственной инфраструктуре или managed inference (Together, Replicate, Modal). Настройка алертов на latency и качество.
Сроки: базовый RAG-прототип — 1-2 недели. Fine-tuning с данными заказчика — 3-6 недель (с учётом подготовки данных). Production-система с мониторингом и переобучением — 2-4 месяца.







