ИИ LLama3 без ограничений: Локальный запуск, GROQ и интеграция в Телеграм бота с помощью Python

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Друзья, приветствую вас в очередной статье. Сегодня я расскажу, как использовать 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. Для этого:

  1. Зайдите в консоль GROQ.

  2. Зарегистрируйтесь и выполните авторизацию.

  3. Перейдите в раздел KEYS.

  4. Нажмите на «Create API Key».

  5. Скопируйте созданный ключ и сохраните его в надёжном месте.

Этих простых действий будет достаточно для дальнейшего использования GROQ в качестве посредника между вашим Python проектом и LLama3.

Преимущества и недостатки использования LLama3 в локальном виде или через GROQ

Локальный запуск LLAMA3

Преимущества:

  1. Контроль над данными и конфиденциальность:

    • Полный контроль над данными, так как они не передаются через сторонние серверы.

  2. Настраиваемость:

    • Возможность полной настройки системы и оптимизации под специфические задачи.

  3. Единовременные затраты:

    • Высокие начальные затраты на оборудование, но отсутствие постоянных расходов на аренду облачных ресурсов.

  4. Отсутствие зависимости от интернета:

    • Модель может работать автономно.

Недостатки:

  1. Высокие начальные затраты:

    • Значительные затраты на покупку и установку оборудования.

  2. Техническое обслуживание:

    • Необходимость регулярного обслуживания и обновления оборудования.

  3. Ограниченная масштабируемость:

    • Масштабирование требует физического обновления или добавления новых машин.

Использование платформы GROQ

Преимущества:

  1. Масштабируемость:

    • Легкость масштабирования вычислительных ресурсов без необходимости физического обновления оборудования.

  2. Обновления и поддержка:

    • Доступ к последним обновлениям и поддержке от команды GROQ.

  3. Экономия времени:

    • Быстрое развертывание и настройка.

  4. Гибкость в оплате:

    • Пока сервис бесплатный, но в будущем появятся платные режимы, позволяющие снять ограничения текущей бесплатной версии.

Недостатки:

  1. Возможные расходы:

    • В будущем платформа станет платной.

  2. Зависимость от интернета:

    • Требуется постоянное интернет-соединение.

  3. Меньший контроль над данными:

    • Данные передаются через сторонние серверы.

  4. Ограниченния платформы (текущие и будущие):

    • Сама платформа уже сейчас устанавливает лимиты и ограничения. К примеру есть лимиты по запросам к модели (скрин ниже).

    • Ещё пример - на данный момент нельзя пользоваться данной платформой с РФ 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 как сообщение от ассистента.

Демо общения с локальной версией LLama3
Демо общения с локальной версией LLama3

Обратите внимание. В данном примере я использовал модуль 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 нет.

Надеюсь, что данные примеры вам понятны. Переходим к боту

Создаем бота

Сегодня мы создадим бота-ассистента, который будет иметь следующие основные функции:

  1. Добавление пользователя в базу данных по клику на "Старт" и присваивание ему статуса "Не в диалоге" / "В диалоге"

  2. Запуск диалога по клику на кнопку «Начать диалог».

  3. Полное удаление истории общения по клику на кнопку «Очистить историю».

Каждый пользователь может находиться в одном из двух состояний: «В диалоге» или «Не в диалоге». Это позволит в будущем расширить функционал бота, добавив интерактивное меню с информацией о нас, выбором моделей и другими опциями.

Логика сохранения истории

Для обеспечения сохранения контекста беседы каждого пользователя мы создадим таблицу с диалогами пользователей. Эта таблица будет содержать следующие поля:

  • 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
openai
  • asyncpg-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'Я запущен						
Источник: https://habr.com/ru/articles/825678/


Интересные статьи

Интересные статьи

Все сталкиваются с индексами на самых ранних стадиях освоения языка, как правило, при изучении списков. Вероятно, вы и так знаете, что индексация в Python начинается с нуля. У нас есть список movies, ...
Евгений Шеленков — руководитель Университета Битрикс24 и тимлид команды «Коммуникации в реальном времени». В компании он с 2010 года — и до сих пор относится к работе как к любимому хобби
Всем привет! На написание этой статьи меня вдохновил автор YouTube канала PeaAshMeter. В своем видео автор показывает простейший генератор 2D мира, который основан на простейшем правиле клеточного авт...
Системы обнаружения Covid-19 на рентгеновских снимках выдают быстрые результаты, в частности информацию о том, насколько серьёзно лёгкие поражены вирусом Covid-19. Традиц...
Мне кажется, в каждом языке программирования есть моменты, которые требуют повышенной концентрации внимания или больше практики для своего понимания. Python в этом плане не исключение, и ...