Когда связь обрывается в самый неподходящий момент
Представьте: землетрясение, лесной пожар или техногенная авария. Вышки сотовой связи уничтожены, интернет отсутствует, а рядом пострадавший, которому нужна первая помощь. ChatGPT в телефоне молчит — нет сети. Вы держите в руках Raspberry Pi (или старый ноутбук) и понимаете: единственный шанс — локальный AI-агент, который знает протоколы МЧС, умеет диагностировать травмы и давать чёткие инструкции. Без облаков, без VPN, без единого HTTP-запроса. Звучит как научная фантастика? Уже нет. В 2026 году собрать такого агента может каждый разработчик, потратив пару выходных.
В этой статье я покажу, как обучить маленькую языковую модель (2-4 млрд параметров) на инструкциях экстренной помощи, сжать её квантизацией и запустить на устройстве без GPU. Всё — по-взрослому: датасет, LoRA, GGUF, офлайн-инференс. И да — без единого обращения к серверу.
Почему обычные модели не подходят для ЧС?
Google, Yandex и OpenAI создали мощные LLM, но в условиях изоляции они бесполезны. Более того, даже локальные «референсные» модели вроде Llama 3.1 8B или Mistral 7B содержат слишком много общих знаний, разбавляющих ответы. Для экстренной помощи требуется детерминированность: в ответ на «остановка дыхания» шаг 1 — проверить сознание, шаг 2 — вызвать скорую (офлайн-симуляция). Крупные модели склонны к «фантазиям» (галлюцинациям), которые в ЧС стоят жизни. Кроме того, 7B-модели требуют 8 GB RAM даже в квантизированном виде — на Raspberry Pi 5 это уже на грани.
Решение — тонкая настройка (fine-tuning) маленькой модели на специализированном датасете, плюс жёсткая квантизация. Так мы получаем скорость, точность и минимальные требования к железу. Аналог — подход, описанный в статье AgentCPM-Explore: 4B параметра на вашем ноутбуке — та же философия, но для других задач.
Выбор модели и датасета: меньше — лучше
1 Кандидаты на роль «спасателя»
На конец мая 2026 года лучшими компактными моделями для офлайн-агента считаются:
- Phi-3-mini (3.8B) — отличное знание инструкций, хорошо понимает русский после адаптации.
- Gemma 2 (2B/5B) — стабильная и безопасная, но требует аккуратного датасета.
- Qwen2.5 (1.5B) — малый размер, достойное качество, подходит для Raspberry Pi.
- FRED-T5 (1.5B/5B) — российская модель, на родном языке работает без адаптации.
Я рекомендую Phi-3-mini из-за сбалансированности размера и качества. Но если вы собираете агента для Raspberry Pi 5 (8GB RAM) — берите Qwen2.5 1.5B или FRED-T5 1.5B. Последний — хороший выбор, если нужен сразу русский язык, как показано в статье Российский локальный AI-агент: сборка с нуля без облака, VPN и подписок.
2 Готовим датасет: только факты, никакого «креатива»
Интернет в ЧС отключён, но датасет мы собираем заранее. Источники:
- Официальные протоколы МЧС России (первая помощь при кровотечениях, переломах, ожогах).
- Международные руководства (ВОЗ, Красный Крест) — перевести на русский.
- Википедия по медицине катастроф — отфильтровать, оставив только проверенные процедуры.
- Симуляционные кейсы из учебников для спасателей.
Формат — пары «пользовательский запрос — ответ агента». Пример:
{
"instruction": "Что делать при артериальном кровотечении из руки?",
"output": "1. Надеть перчатки (если есть). 2. Найти точку прижатия артерии (плечевая). 3. Наложить жгут выше раны на 5-7 см. 4. Записать время наложения жгута. 5. Вызвать помощь (если есть сигнал). 6. Не снимать жгут до прибытия медиков."
}Важно: ответы должны быть однозначными, без вариантов. Для этого используем формат chain-of-thought с жёсткой схемой — модель учится выдавать шаги строго по порядку.
Объём датасета: 5-10 тысяч примеров достаточно для маленькой модели. Чтобы избежать переобучения, добавляем негативные примеры (вопрос не по теме — „расскажи анекдот“) с ответом-заглушкой: „Я офлайн-агент для ЧС. Задайте вопрос о первой помощи.“
Тренируем агента: LoRA и Unsloth
Для тонкой настройки на малых ресурсах используем LoRA (Low-Rank Adaptation). Это позволяет обновлять только небольшие матрицы, экономя видеопамять. Я предпочитаю библиотеку Unsloth — она ускоряет обучение в 2-3 раза и поддерживает автоматическую квантизацию.
Код для обучения на Google Colab (или локально с GPU 8GB+):
from unsloth import FastLanguageModel
import torch
model_id = "microsoft/Phi-3-mini-4k-instruct" # самая актуальная на май 2026
model, tokenizer = FastLanguageModel.from_pretrained(
model_id,
max_seq_length=2048,
dtype=torch.bfloat16,
load_in_4bit=True, # сразу квантизация для экономии памяти
)
model = FastLanguageModel.get_peft_model(
model,
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
use_gradient_checkpointing=True,
)
# загрузка датасета (формат Alpaca)
from datasets import load_dataset
dataset = load_dataset("json", data_files="emergency_care.json")
# токенизация
def format_prompt(sample):
return tokenizer.apply_chat_template([
{"role": "user", "content": sample["instruction"]},
{"role": "assistant", "content": sample["output"]}
], tokenize=False)
dataset = dataset.map(lambda x: tokenizer(format_prompt(x),
truncation=True, padding="max_length", max_length=2048), batched=False)
trainer = FastLanguageModel.get_trainer(
model, tokenizer, dataset["train"],
args=dict(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
num_train_epochs=3,
learning_rate=2e-4,
logging_steps=10,
save_steps=200,
)
)
trainer.train()
# сохраняем LoRA-веса
model.save_pretrained("phi3_lora_emergency")
Ошибка новичка: обучение на слишком большом `num_train_epochs` (5+). При малом датасете модель переобучается и начинает выдавать выученные фразы даже на нерелевантные вопросы. 2-3 эпохи — оптимум.
Конвертация в GGUF и квантизация
Чтобы запустить модель на устройстве без GPU, конвертируем LoRA-адаптированные веса в формат GGUF (с помощью llama.cpp). Плюс — применяем квантизацию Q4_K_M, которая сжимает модель в 4 раза с минимальной потерей точности.
# сначала мержим LoRA с базовой моделью
python merge_lora.py --base_model microsoft/Phi-3-mini-4k-instruct \
--lora_model phi3_lora_emergency --output merged_phi3_emergency
# конвертируем в FP16 GGUF
python -m llama.cpp.convert merged_phi3_emergency --outfile phi3_emergency_f16.gguf
# квантизируем в Q4_K_M
./quantize phi3_emergency_f16.gguf phi3_emergency_q4km.gguf Q4_K_M
Итоговый файл для Phi-3-mini весит около 2.3 ГБ — помещается на MicroSD. Для Qwen2.5 1.5B — менее 1 ГБ.
Развёртывание: от Raspberry Pi до ноутбука
Готовый GGUF-файл загружаем на устройство. Запуск через llama.cpp или его обёртку (например, Ollama, но в строго офлайн-режиме). Самый простой способ — написать скрипт на Python с llama-cpp-python:
from llama_cpp import Llama
model_path = "phi3_emergency_q4km.gguf"
llm = Llama(model_path=model_path, n_ctx=2048, n_threads=4)
def ask_agent(prompt):
output = llm(
prompt=f"<|user|>{prompt}\n<|assistant|>",
max_tokens=512,
temperature=0.1, # минимальная температура для детерминизма
stop=["<|user|>", "<|endoftext|>"],
)
return output["choices"][0]["text"]
# тест
print(ask_agent("Как остановить венозное кровотечение?"))
На Raspberry Pi 5 (8GB RAM) инференс занимает 2-3 секунды — приемлемо для ЧС. На ноутбуке с CPU Intel i5 — менее секунды.
Чтобы агент был готов к любым сценариям, добавьте функциональные триггеры: например, ключевое слово "экстренная помощь" запускает только заученные протоколы, а не генерацию. Такой подход напоминает то, что описано в статье Как создать ИИ-агента для ЧС, работающего без интернета: опыт команды Сбера — они используют гибрид правил и LLM.
Нюансы, которые спасут жизнь (и нервы)
- Жёсткий fallback. Если модель не уверена (низкая вероятность первого токена) — выдаём зашитое сообщение: «Следуйте общим правилам: не навреди, вызови помощь». Не давайте права на рискованные действия.
- Слепое тестирование. Проверьте работу агента в сценариях с шумом: «У меня кровь идёт, что делать?» — модель должна распознать запрос и выдать шаги.
- Периодическое обновление. При появлении интернета можно загружать новую версию GGUF. Но в офлайн-режиме предусмотрите возможность обновления через USB-флешку.
- Защита от случайного изменения. Файлы модели readonly, загрузчик проверяет хеш SHA256.
Ошибки, которые я видел в реальных проектах
- Галлюцинации из-за высокой температуры. Кто-то оставил temperature=0.7 — модель начала «творить»: «при артериальном кровотечении приложите лёд» (неправильно). Для ЧС temperature ≤ 0.1.
- Игнорирование контекста безопасности. Один разработчик обучил модель на форумах — агент советовал «промыть рану водкой». В датасете должны быть только официальные протоколы.
- Отсутствие ограничения токенов. Модель может уйти в бесконечный цикл «примите… примите…». Установите
max_tokensи стоп-слова. - Слишком большой контекст. Для кратких инструкций 1024 токенов достаточно. Больший контекст только замедляет инференс.
Совет, который вы не ожидали
Ваш офлайн-агент не должен заменять человека. Даже самая точная модель может ошибиться в нестандартном сценарии. Лучшее решение — встроить в агента «режим ассистента», который задаёт уточняющие вопросы и направляет пользователя, а не даёт готовые ответы. Например: «Вы уверены, что кровотечение артериальное? Опишите цвет крови. Если она алая и бьёт фонтаном — накладывайте жгут. Если тёмная и течёт — давящая повязка». Такой диалог снижает риск ошибки и повышает доверие.
Следующий шаг — добавить распознавание голоса (Whisper в офлайне) и TTS (эхо-ответ). Но это уже тема отдельной статьи. А пока — соберите своего первого агента и положите его в рюкзак. Вдруг пригодится.