Друзья, приветствую вас в очередной статье. Сегодня я расскажу, как использовать LLAMA3 ИИ в своих проектах. После небольшой подготовки мы приступим к созданию полноценного Telegram бота.
Сегодня мы:
Научимся устанавливать LLama3 на локальную машину.
Научимся бесплатно запускать LLama3 через платформу GROQ.
Разберемся с преимуществами и недостатками первого и второго способа развертывания LLama3.
Напишем полноценного Telegram бота с использованием aiogram3, который сможет работать как с локальной версией LLAMA3, так и через сервис GROQ (технически он сможет работать с любой подключенной нейросетью).
Запустим Telegram бота на VPS сервере (опционально).
Подготовка
Для того чтобы следовать этому руководству, вам потребуется:
VPS сервер (важно, чтобы с европейским или США API).
База данных PostgreSQL (о том, как запустить её за пару минут, я писал [ТУТ]).
Базовые знания по написанию ботов через aiogram3 (в моём профиле на Хабре вы найдёте множество публикаций, в которых подробно рассмотрена тема создания Telegram ботов).
Установленный Docker на локальной машине и на VPS сервере (если вы новичок, установите Docker Desktop).
Надеюсь, что подготовку вы уже выполнили.
Развертывание локальной версии нейросети LLAMA с использованием Docker
Откройте консоль и выполните следующую команду:
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollamaЭта команда развернет локальный образ LLAMA, который будет работать исключительно на вашем процессоре. Также существует вариант использования Nvidia GPU, с инструкциями можно ознакомиться [здесь].
Для запуска самой модели выполните команду:
docker exec -it ollama ollama run llama3:8bЭта команда загрузит и запустит языковую модель LLAMA3:8b (4.7GB). Доступна также более крупная версия LLama3, 70b (40GB). Вы можете запускать и другие модели, список которых доступен [здесь].
Чтобы запустить другую модель, используйте команду:
docker exec -it ollama ollama run model_name:tag
Для выхода из диалога с LLM отправьте команду /bye, затем последовательно выполните CTRL+P и CTRL+Q, чтобы выйти из интерактивного режима.
Обратите внимание. Так вы просто свернете контейнер, но он все равно будет запущен. Если вы хотите удалить контейнер, то воспользуйтесь командами:
docker stop ollama
docker rm ollama
docker rmi ollama/ollamaОбратите внимание. После остановки (удаления) контейнера ollama локальное взаимодействие с ним будет невозможным!
Важно: перед использованием локальных ИИ выполните загрузку самой модели. Самый простой способ – запустить диалог с моделью, как описано выше, так вы и загрузку выполните, и проверите, что всё корректно работает.
Использование GROQ для взаимодействия с LLAMA3
Альтернативой локальному запуску LLAMA3 является использование сервиса GROQ. Для этого:
Зайдите в консоль GROQ.
Зарегистрируйтесь и выполните авторизацию.
Перейдите в раздел KEYS.
Нажмите на «Create API Key».
Скопируйте созданный ключ и сохраните его в надёжном месте.
Этих простых действий будет достаточно для дальнейшего использования GROQ в качестве посредника между вашим Python проектом и LLama3.
Преимущества и недостатки использования LLama3 в локальном виде или через GROQ
Локальный запуск LLAMA3
Преимущества:
Контроль над данными и конфиденциальность:
Полный контроль над данными, так как они не передаются через сторонние серверы.
Настраиваемость:
Возможность полной настройки системы и оптимизации под специфические задачи.
Единовременные затраты:
Высокие начальные затраты на оборудование, но отсутствие постоянных расходов на аренду облачных ресурсов.
Отсутствие зависимости от интернета:
Модель может работать автономно.
Недостатки:
Высокие начальные затраты:
Значительные затраты на покупку и установку оборудования.
Техническое обслуживание:
Необходимость регулярного обслуживания и обновления оборудования.
Ограниченная масштабируемость:
Масштабирование требует физического обновления или добавления новых машин.
Использование платформы GROQ
Преимущества:
Масштабируемость:
Легкость масштабирования вычислительных ресурсов без необходимости физического обновления оборудования.
Обновления и поддержка:
Доступ к последним обновлениям и поддержке от команды GROQ.
Экономия времени:
Быстрое развертывание и настройка.
Гибкость в оплате:
Пока сервис бесплатный, но в будущем появятся платные режимы, позволяющие снять ограничения текущей бесплатной версии.
Недостатки:
Возможные расходы:
В будущем платформа станет платной.
Зависимость от интернета:
Требуется постоянное интернет-соединение.
Меньший контроль над данными:
Данные передаются через сторонние серверы.
Ограниченния платформы (текущие и будущие):
Сама платформа уже сейчас устанавливает лимиты и ограничения. К примеру есть лимиты по запросам к модели (скрин ниже).
Ещё пример - на данный момент нельзя пользоваться данной платформой с РФ IP адресов. При чем, вы не только не сможете без VPN зайти на сайт, но ещё и VPN должен стоять на вашем компьютере (сервере, если IP РФ), если вы в РФ и если вы будете использовать GROQ в своих проектах.

Выбор между локальным запуском LLAMA и использованием платформы GROQ зависит от ваших конкретных нужд и приоритетов. Для полного контроля и автономности лучше подходит локальный запуск, несмотря на высокие начальные затраты и необходимость обслуживания. Для гибкости, быстрого масштабирования и меньших начальных затрат оптимальным будет использование платформы GROQ, несмотря на постоянные расходы и зависимость от интернет-соединения.
Теперь давайте рассмотрим программное использование LLama3 с локальным запуском и запуском через платформу GROQ.
Я подготовил две демо-версии, изучив которые, вы поймёте, как происходит программное взаимодействие с LLAMA3 через Python.
Демо локального использования
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1',
api_key='ollama',
)
dialog_history = []
while True:
user_input = input("Введите ваше сообщение ('stop' для завершения): ")
if user_input.lower() == "stop":
break
# Добавляем сообщение пользователя в историю диалога
dialog_history.append({
"role": "user",
"content": user_input,
})
response = client.chat.completions.create(
model="llama3:8b",
messages=dialog_history,
)
# Извлекаем содержимое ответа
response_content = response.choices[0].message.content
print("Ответ модели:", response_content)
# Добавляем ответ модели в историю диалога
dialog_history.append({
"role": "assistant",
"content": response_content,
})
Давайте разберемся с этим кодом.
Импорт и настройка клиента
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1',
api_key='ollama',
)Здесь мы импортируем библиотеку OpenAI и создаем экземпляр клиента OpenAI, указывая базовый URL для API (локальный сервер на порту 11434) и API-ключ (в данном случае 'ollama').
Такую возможность мы получаем после того как локально развернули Docker контейнер Ollama. Далее, выполняя запросы о которых поговорим далее, мы имитируем диалог с ботом через консоль (описывал выше).
Инициализация истории диалога
dialog_history = []Создаем пустой список dialog_history, который будет хранить историю сообщений диалога между пользователем и моделью. Такой-же, но более продвинутый формат хранения истории мы будем использовать в нашем боте.
Основной цикл для взаимодействия с пользователем
while True:
user_input = input("Введите ваше сообщение ('stop' для завершения): ")
if user_input.lower() == "stop":
breakЗапускаем бесконечный цикл, который будет принимать ввод от пользователя. Если пользователь введет 'stop', цикл прерывается.
Добавление сообщения пользователя в историю диалога
dialog_history.append({
"role": "user",
"content": user_input,
})Сообщение пользователя добавляется в dialog_history в виде словаря с ключами role (роль 'user') и content (содержимое сообщения).
Отправка запроса модели и получение ответа
response = client.chat.completions.create(
model="llama3:8b",
messages=dialog_history,
)Отправляется запрос к модели llama3:8b (если разворачивали контейнер с Llama3, то на вашем компьютере уже установлена модель llama3:8b, иначе загрузите модель отдельно) с текущей историей диалога. Метод client.chat.completions.create создает завершение чата на основе переданных сообщений.
Обработка ответа модели
response_content = response.choices[0].message.content
print("Ответ модели:", response_content)Ответ модели извлекается из объекта response и выводится на экран.
Добавление ответа модели в историю диалога
dialog_history.append({
"role": "assistant",
"content": response_content,
})Ответ модели добавляется в dialog_history как сообщение от ассистента.

Обратите внимание. В данном примере я использовал модуль openai, а это значит, что данный клиент будет работать в любом боте, который использовал нейронки ChatGPT, Bing и так далее (сейчас GitHub завален проектами, использующими библиотеку openai).
Демо клиента через GROQ
from groq import Groq
from decouple import config
client = Groq(
api_key=config("GROQ_API_KEY"),
)
dialog_history = []
while True:
user_input = input("Введите ваше сообщение ('stop' для завершения): ")
if user_input.lower() == "stop":
break
# Добавляем сообщение пользователя в историю диалога
dialog_history.append({
"role": "user",
"content": user_input,
})
models = ["gemma-7b-it", "llama3-70b-8192", "llama3-8b-8192", "mixtral-8x7b-32768"]
chat_completion = client.chat.completions.create(
messages=dialog_history,
model=models[1],D
)
response = chat_completion.choices[0].message.content
print("Ответ модели:", response)
# Добавляем ответ модели в историю диалога
dialog_history.append({
"role": "assistant",
"content": response,
})
Особо внимательные могут заметить, что синтаксис модуля GROQ не особо отличается от синтаксиса OPENAI и это совсем не случайно. Ведь, если мы посмотрим под капот модуля groq, то увидим что основывается он на openai.
А это, как вы поняли, нам на руку.
Импорт и настрйка клиента
from groq import Groq
from decouple import config
client = Groq(
api_key=config("GROQ_API_KEY"),
)Я использовал модуль python-decouple, чтоб импортировать из файла .env GROQ_API_KEY.
Доступные модели:
models = ["gemma-7b-it", "llama3-70b-8192", "llama3-8b-8192", "mixtral-8x7b-32768"]На данный момент GROQ поддерживает представленные выше модели. В коде я взял за основу "llama3-70b-8192". Это там самая модель, которая весит более 40GB и самое приятное тут то, что скачивать модель нам не нужно, а достаточно получить у GROQ api key и установить модуль groq.
В остальном отличий от работы со своей локальной моделью через openai нет.
Надеюсь, что данные примеры вам понятны. Переходим к боту
Создаем бота
Сегодня мы создадим бота-ассистента, который будет иметь следующие основные функции:
Добавление пользователя в базу данных по клику на "Старт" и присваивание ему статуса "Не в диалоге" / "В диалоге"
Запуск диалога по клику на кнопку «Начать диалог».
Полное удаление истории общения по клику на кнопку «Очистить историю».
Каждый пользователь может находиться в одном из двух состояний: «В диалоге» или «Не в диалоге». Это позволит в будущем расширить функционал бота, добавив интерактивное меню с информацией о нас, выбором моделей и другими опциями.
Логика сохранения истории
Для обеспечения сохранения контекста беседы каждого пользователя мы создадим таблицу с диалогами пользователей. Эта таблица будет содержать следующие поля:
id: уникальный идентификатор диалога (автоинкрементируемый номер).
user_id: Telegram ID пользователя.
message: JSON с сообщением бота или пользователя.
Такой подход позволит нам сохранять историю диалога для каждого пользователя по его Telegram ID, а также обеспечить возможность очистки истории.
Хранение информации о пользователе
Для хранения информации о пользователе создадим таблицу users. В этой таблице будут следующие поля:
user_id: уникальный идентификатор пользователя в Telegram.
user_login: имя пользователя в Telegram.
full_name: полное имя пользователя.
in_dialog: текущее состояние пользователя («В диалоге» (True) или «Не в диалоге» (False)).
date_reg: дата и время регистрации пользователя.
Создание этих таблиц позволит эффективно управлять данными пользователей и их диалогами, обеспечивая гибкость и масштабируемость нашего бота-ассистента.
Подготовка перед написанием кода
Начну с того, что весь код бота можно найти в моем публичном репозитории Easy_LLama3_Bot. Там вы найдете бота, демки для работы с локальной и GROQ версией Llama3 и пример настройки Dockerfile для быстрого запуска на VPS сервере.
Зависимости (requirementsl.txt)
asyncpg-lite~=0.3.1.3
aiogram~=3.7.0
python-decouple
groq
pytz
openaiasyncpg-lite - библиотека для асинхронной работы с PostgreSQL (делал подробное описание Asynpg-lite: лёгкость асинхронных операций на PostgreSQL с SQLAlchemy)
aiogram3 - фреймворк для создания телеграмм ботов через Python (в моём профиле на Хабре вы найдёте множество публикаций, в которых подробно рассмотрена тема создания Telegram ботов на aiogram3)
python-decouple - модуль для удобной работы с .env
groq и openai описывал выше. Выберите для своего бота один из вариантов.
pytz - простой модуль для работы с часовыми поясами
ENV-файл (.env)
GROQ_API_KEY=your_groq_token
BOT_API_KEY=your_bot_token
ADMINS=admin1,admin2
ROOT_PASS=your_root_password
PG_LINK=postgresql://username:password@host:port/dbnameЗамените данные на свои. Предварительно не забудьте узнать свой телеграмм ID, развернуть базу данных и создать токен бота и токен GROQ_API. О том как создавать токен телеграмм бота через BotFather вы можете узнать тут или, в целом, на просторах интернета.
Структура проекта
- db_handler
- __init__.py: Инициализация модуля.
- db_funk.py: Функции для взаимодействия с PostgreSQL.
- handlers
- __init__.py: Инициализация модуля.
- user_router.py: Основной и единственный роутер в котором весь код
- keyboards
- __init__.py: Инициализация модуля.
- kbs.py: Файл со всеми клавиатурами.
- utils
- __init__.py: Инициализация модуля.
- utils.py: Файл с утилитами.
- .env
- .dockerignorefile
- Dockerfile
- Makefile: файл для удобного запуска и управления контейнерами
- .gitignorefile
- aiogram_run.py: файл для запуска бота
- create_bot.py: файл с настройками бота
- llama_groq_demo.py: демка LLama3с работой через GROQ
- llama_localhost_demo.py: демка LLama3с с локальным запуском
- README.md: Короткое описание проекта с GitHubФайл с настройками бота (create_bot.py):
import logging
from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from asyncpg_lite import DatabaseManager
from decouple import config
from groq import Groq
from openai import OpenAI
client_groq = Groq(api_key=config("GROQ_API_KEY"))
local_client = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')
# получаем список администраторов из .env
admins = [int(admin_id) for admin_id in config('ADMINS').split(',')]
# инициализируем логирование и выводим в переменную для отдельного использования в нужных местах
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# инициализируем объект, который будет отвечать за взаимодействие с базой данных
db_manager = DatabaseManager(db_url=config('PG_LINK'), deletion_password=config('ROOT_PASS'))
# инициализируем объект бота, передавая ему parse_mode=ParseMode.HTML по умолчанию
bot = Bot(token=config('BOT_API_KEY'), default=DefaultBotProperties(parse_mode=ParseMode.HTML))
# инициализируем объект бота
dp = Dispatcher()
Если вы читали мои статьи по Aiogram3 то вам должно быть все понятно. Единственное на что хочу обратить внимание - это настройка клиентов для работы с нейронками.
Вам необходимо выбрать один вариант или GROQ или локальную версию. В коде вывел два для демонстрации.
Файл для запуска бота (aiogram_run.py):
import asyncio
from create_bot import bot, dp, admins
from db_handler.db_funk import get_all_users
from handlers.user_router import user_router
from aiogram.types import BotCommand, BotCommandScopeDefault
# Функция, которая настроит командное меню (дефолтное для всех пользователей)
async def set_commands():
commands = [BotCommand(command='start', description='Старт'),
BotCommand(command='restart', description='Очистить диалог')]
await bot.set_my_commands(commands, BotCommandScopeDefault())
# Функция, которая выполнится когда бот запустится
async def start_bot():
await set_commands()
count_users = await get_all_users(count=True)
try:
for admin_id in admins:
await bot.send_message(admin_id, f'Я запущен 