Легковесные локальные LLM для Python-агентов
Обзор простых и легковесных локальных LLM (3-7B) для создания агента на Python. Как запускать модели локально, квантование, архитектура агента, пример кода и безопасность. Подходят ли для вызова функций?
Какие существуют простые и легковесные языковые модели (LLM) для локального использования? Я планирую создать локального агента на основе LLM, который будет выполнять мои Python-функции на основе их описаний. Подойдут ли для таких небольших задач какие-то легковесные языковые модели?
Да — для локального агента, выполняющего Python‑функции по их описаниям, вполне подойдут легковесные локальные LLM. Модели 3–7B (например LLaMA 2 7B, Vicuna/GPT4All‑«lite», MPT‑7B или компактные StableLM/FLAN‑T5‑3B) при квантовании и запуске через обёртки для llm python (llama.cpp / llama-cpp-python, GPT4All) дают приемлемую точность и скорость для задач выбора и заполнения аргументов функций. Важнее не только модель, но и схема регистрации инструментов, жёсткая валидация аргументов и безопасный запуск кода.
Содержание
- Какие легковесные локальные LLM подходят для агента на Python
- Как запускать LLM локально: варианты и квантование
- Архитектура локального агента и алгоритм вызова Python‑функций
- Практические рекомендации: модель, квантование и железо
- Безопасность и валидация при удалённом вызове функций
- Быстрый пример: минимальный агент на Python + llama.cpp
- Частые ошибки и советы по отладке
- Источники
- Заключение
Какие легковесные локальные LLM подходят для агента на Python
Если коротко: для простых действий типа выбора функции и заполнения аргументов часто хватает моделей 3–7B — они легче разворачиваются и достаточно «понимают» инструкции. Под «легковесными llm» чаще имеют в виду модели с параметрами от ~1B до 7B либо тяжёлые модели, но сильно квантованные (4‑бит, GGML/GPTQ). Ниже — подборка реалистичных вариантов и когда их использовать.
-
LLaMA 2 (7B) — хороший компромисс между качеством и доступностью; широко используется в локальных установках (есть чат‑варианты). Подходит, если хотите «универсальную» инструкционную модель. См. страницу LLaMA у Meta: https://ai.meta.com/llama.
Плюсы: отличная база, много обёрток; минусы: требуется принять лицензию и, для скорости, квантование/обёртки. -
Vicuna (7B, community fine‑tune) — версия LLaMA‑типа, заточенная под диалог и инструкции; часто даёт более «практичные» ответы на команды. Подробнее: https://vicuna.lmsys.org/.
-
GPT4All (локальные сборки) — проект с CPU‑оптимизированными сборками и удобными Python‑клиентами; хорош для быстрого прототипа на локальной машине: https://gpt4all.io и https://github.com/nomic-ai/gpt4all.
Плюсы: простая упаковка, готовые модели для CPU; минусы: качество у «lite»‑вариантов ограничено. -
MPT‑7B‑Instruct (MosaicML) — хорош для инструкций и программирования, часто конкурентоспособен по качеству для 7B‑моделей: https://www.mosaicml.com/models/mpt.
-
StableLM / FLAN‑T5 (3B и ниже) — если задача строго структурированная (выбор функции, заполнение аргументов), компактные seq2seq‑модели (flan‑t5‑small/base или stablelm‑3b) на CPU будут быстрыми и дешёвыми; жить с чуть меньшей «гибкостью» ответа. См. https://huggingface.co для примеров моделей.
Где искать модели и готовые билды? Основной хаб — Hugging Face (https://huggingface.co). Для локального интерфейса и конвертации моделей часто используют проекты вроде llama.cpp (для CPU/ggml) и локальные веб‑UI: https://github.com/ggerganov/llama.cpp, https://github.com/oobabooga/text-generation-webui.
Как запускать LLM локально: варианты и квантование
Есть два основных подхода для llm python‑интеграции: «GPU + transformers/bitsandbytes» и «CPU‑оптимизированные ggml/llama.cpp» — выбор зависит от железа.
- CPU (без дискретной GPU)
- Используйте llama.cpp + ggml‑веса (4‑бит) и Python‑обёртку llama‑cpp‑python: https://github.com/ggerganov/llama.cpp и https://github.com/abetlen/llama-cpp-python.
- GPTQ‑квантованные файлы (4‑bit GPTQ) дают существенную экономию памяти и приемлемую скорость; инструменты для GPTQ: https://github.com/qwopqwop200/GPTQ-for-LLaMa.
- GPU (NVIDIA/AMD)
- Hugging Face Transformers + bitsandbytes позволяют запускать модели в 4/8‑битном режиме на GPU (значительно быстрее): https://github.com/TimDettmers/bitsandbytes и https://huggingface.co/blog/qlora для методик обучения/дообучения с низкой памятью.
- 7B модели с 4‑бит квантованием часто помещаются в 8–10 GB VRAM; 13B требует примерно 12–16 GB (зависит от сборки и библиотек).
- Быстрая сборка UI / эксперимент
- text‑generation‑webui от oobabooga умеет запускать множество моделей через llama.cpp, transformers и даёт удобный веб‑интерфейс: https://github.com/oobabooga/text-generation-webui.
- Как выбрать: коротко
- Только CPU + отклик в секундах: выбирайте 3B или 7B в ggml‑Q4.
- GPU 8GB+: 7B в 4‑бит.
- Нужна высокая точность по коду/пониманию: думайте о 7B+ или более качественном 7B‑клиенте (Vicuna/MPT), либо о локальном GPU 24GB для 13B/30B.
Архитектура локального агента и алгоритм вызова Python‑функций
Как заставить модель «выбирать функцию и заполнять аргументы»? Типичная архитектура:
- Реестр инструментов (tools)
- Для каждой функции храните: имя, описание на естественном языке, схема аргументов (типы), возможные ограничения.
- Пример: {“name”:“get_user_balance”,“desc”:“вернёт баланс пользователя по id”,“args”:{“user_id”:“int”}}.
- Промпт. Дайте модели чёткое правило вывода
- Просите ответить строго в JSON: {“tool”:“<имя>”,“args”:{…}}. Добавьте 1–2 демонстрационных примера (few‑shot). Понижайте температуру (temperature=0–0.2) для детерминизма.
- Парсинг и валидация
- Парсите JSON (json.loads). Валидируйте типы (pydantic или ручная проверка). Если невалидно — возвращайте ошибку модели и попросите повторить.
- Выполнение в защищённой песочнице
- Вызывайте только заранее зарегистрированные функции; не выполняйте произвольный код. Ограничьте ресурсы (время выполнения, память), запускайте в отдельном процессе/контейнере при возможности.
- Итоговая цепочка
- Модель выбирает tool + args → валидатор проверяет → выполняется функция → возвращается результат пользователю (и при необходимости — логируется).
Фреймворки, которые облегчают создание таких агентов: LangChain (документы и «tools/agents»): https://python.langchain.com/en/latest/, и LlamaIndex для RAG/поиска по документам: https://github.com/jerryjliu/llama_index.
Практические рекомендации: модель, квантование и железо
-
Что выбрать для вашего сценария (локальный агент, вызов Python‑функций)?
-
Если функции — простые (вызов по имени, базовые аргументы), хватит 3B‑модели или 7B в 4‑бит.
-
Если нужно сложное понимание описаний/контекста (много документации, сложные типы), лучше 7B (Vicuna/LLaMA 2 7B) или MPT‑7B‑Instruct.
-
Квантование
-
GPTQ (4‑bit) — распространённый выбор для экономии памяти при минимальной потере качества: https://github.com/qwopqwop200/GPTQ-for-LLaMa.
-
QLoRA — если нужно дообучать модель локально при ограниченных ресурсах: https://huggingface.co/blog/qlora.
-
Параметры запуска (практика)
-
Температура 0–0.2 для надёжного выбора инструментов.
-
Установите явную инструкцию «возвращай только JSON, без лишних слов».
-
Ограничьте max_tokens, чтобы модель не «разбежалась».
-
Железо: ориентиры (примерно)
-
CPU only: комфортно — 1–3B; 7B — возможен, но медленнее (секунды за ответ).
-
GPU 8 GB: 7B (с 4‑бит квантованием) — плавно.
-
GPU 16+ GB: 13B и выше — более низкая задержка.
Безопасность и валидация при удалённом вызове функций
Выполнение Python‑функций по указанию модели — это потенциальный риск. Несколько практических мер:
- Белый список функций: регистрируйте только безопасные, проверенные callable. Никогда не выполняйте код, полученный от модели через eval/exec.
- Валидация аргументов: используйте pydantic/cerberus для строгой проверки типов и границ.
- Запуск в песочнице: отдельный процесс, контейнер или sandbox (например, Firejail, Docker с ограничениями). Таймауты и лимиты памяти обязательны.
- Логирование и откат: храните входы/выходы и возможность отката (если функция меняет состояние).
- Ограничьте побочные эффекты: по возможности разделяйте функции на «чтение» и «изменение данных», и требуйте подтверждение для действий, влияющих на критичные ресурсы.
Быстрый пример: минимальный агент на Python + llama.cpp
Ниже — упрощённый рабочий шаблон. Предполагается, что у вас есть ggml‑модель и обёртка llama‑cpp‑python.
from llama_cpp import Llama
import json
import time
# 1) Реестр инструментов
def add(a: int, b: int):
return a + b
TOOLS = {
"add": {
"fn": add,
"args": {"a": int, "b": int},
"desc": "Сложить два целых числа: a и b"
}
}
# 2) Инициализация LLM (пример для ggml Q4_0)
llm = Llama(model_path="models/llama-7b.ggml.q4_0.bin")
def build_prompt(funcs):
funcs_desc = "\n".join([f"{name}: {meta['desc']}" for name, meta in funcs.items()])
prompt = f"""
Ты — ассистент, выбирающий одну из функций по описанию и возвращающий строго JSON в формате:
{{"tool":"<имя>","args":{{...}}}}
Функции:
{funcs_desc}
Пример:
Описание: "прибавь 2 к 3"
Ответ:
{{"tool":"add","args":{{"a":2,"b":3}}}}
Описание: "пожалуйста, {{} }}" # затем подставляем реальную задачу
"""
return prompt
# 3) Обработка запроса и вызов
user_desc = "сосчитай сумму 7 и 5"
prompt = build_prompt(TOOLS) + "\nОписание: " + user_desc + "\nОтвет:"
resp = llm.create(prompt=prompt, max_tokens=100, temperature=0.0)
text = resp['choices'][0]['text'].strip()
# 4) Парсинг и валидация
try:
obj = json.loads(text)
name = obj.get("tool")
args = obj.get("args", {})
if name in TOOLS:
# простая валидация типов
for k, t in TOOLS[name]["args"].items():
if k not in args:
raise ValueError(f"missing arg {k}")
args[k] = t(args[k])
result = TOOLS[name]["fn"](**args)
print("Result:", result)
else:
print("Unknown tool:", name)
except Exception as e:
print("Parse/validation error:", e)
Комментарий: модель может иногда не вернуть чистый JSON — добавьте препроцессинг (регулярные выражения, попытки извлечь JSON между фигурными скобками) и, при необходимости, повторите запрос с исправлением.
Частые ошибки и советы по отладке
- Модель не вернула JSON или вернула текст с комментариями — снизьте температуру, добавьте демонстрации и жёстко просите «только JSON».
- Аргументы пришли в неверном типе — валидируйте и приводите типы вручную.
- Задержки на CPU слишком большие — пробуйте более лёгкую модель (3B) или используйте quantized‑вариант.
- Модель «галлюцинирует» имя функции — укажите более явные, однозначные описания инструментов и примеры.
- Проблемы с памятью при загрузке модели — переходите на GPTQ/ggml‑квантование или уменьшайте batch/контекст.
Источники
- LLaMA (Meta): https://ai.meta.com/llama
- Vicuna project: https://vicuna.lmsys.org/
- GPT4All (site): https://gpt4all.io
- GPT4All (GitHub): https://github.com/nomic-ai/gpt4all
- llama.cpp (GitHub): https://github.com/ggerganov/llama.cpp
- llama‑cpp‑python (GitHub): https://github.com/abetlen/llama-cpp-python
- text‑generation‑webui (oobabooga): https://github.com/oobabooga/text-generation-webui
- GPTQ for LLaMa (GitHub): https://github.com/qwopqwop200/GPTQ-for-LLaMa
- QLoRA (Hugging Face blog): https://huggingface.co/blog/qlora
- bitsandbytes (GitHub): https://github.com/TimDettmers/bitsandbytes
- MPT models (MosaicML): https://www.mosaicml.com/models/mpt
- LangChain docs (agents/tools): https://python.langchain.com/en/latest/
- LlamaIndex (GitHub): https://github.com/jerryjliu/llama_index
- Hugging Face (models hub): https://huggingface.co
Заключение
Для локального агента на Python зачастую достаточно легковесных локальных LLM в диапазоне 3–7B, особенно если применять квантование и обёртки для llm python (llama.cpp, GPT4All и пр.). Главные усилия стоит вложить в чёткий реестр инструментов, надёжную валидацию аргументов и безопасный механизм исполнения — тогда даже компактная модель будет надёжно вызывать ваши Python‑функции.