Назад
  04.06.2024
Создаем простой AI чат-бот Telegram с помощью Ollama и нескольких строк кода на Python

Чтобы создать несложного чат-бота для Telegram, который получит мощь LLM llama3 вам необходимо выполнить несколько простых шагов. Все будем делать под Ubuntu 22.04 с использованием GPU NVIDIA (подойдут модели RTX2xxx и новее от 8 Гб видеопамяти). Также убедитесь, что у вас на компьютере минимум 16 Гб ОЗУ.

Перед началом работы проверьте, установлены ли у вас драйвера от Nvidia и CUDA вот по этой инструкции.

Устанавливаем Ollama

  1. Скачиваем и устанавливаем Ollama

curl -L https://ollama.com/download/ollama-linux-amd64 -o /usr/bin/ollama
chmod +x /usr/bin/ollama
sudo useradd -r -s /bin/false -m -d /usr/share/ollama ollama
  1. Запускаем Ollama как сервис. Создаем файл сервиса:

tee /usr/lib/systemd/system/ollama.service > /dev/null <<EOF
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=*"

[Install]
WantedBy=default.target
EOF
Insert your text here
  1. Включаем сервис ollama:

sudo systemctl daemon-reload
sudo systemctl enable ollama
sudo systemctl start ollama
  1. Скачиваем модель llama3:8b

ollama run llama3 | exit

Вы можете скачать и установить любую модель, которые поддерживает Ollama, например Phi3 или Codestral. Полный список моделей можно посмотреть по ссылке. А нажав на конкретную модель, можно выбрать также ее размер, контекст и тип.

  1. Перезапускаем сервис:

ollama run llama3 | exit

Создаем чат-бот

1. Устанавливаем Python 3.10:

sudo apt install python3.10

2. Создаем виртуальное окружение:

python3 -m venv venv

3. Активируем данное окружение:

source venv/bin/activate

При успешной активации в строке приглашения появится имя виртуального окружения в скобках:

(venv) user@you_server:~$

4. Ставим в окружении необходимые библиотеки:

pip install python-telegram-bot ollama nest_asyncio

8. Заходим на https://t.me/BotFather , создаем бота и получаем его токен.

9. Создаем файл bot.py со следующим содержанием (можно в корне вашей домашней директории). Данный код позволяет работать чат-боту в асинхронном режиме, обслуживая несколько пользователей, а также хранить контекст на 8 последних сообщений:

import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters
import ollama
import nest_asyncio

nest_asyncio.apply()

# Включаем ведение журнала
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

# Токен, который вы получили от @BotFather
TOKEN = 'YOU_TELEGRAM_BOT_TOKEN'# Replace with your actual token

# Словарь для хранения данных пользователей
user_ids = {}
context_memory = {}

# Функция для обработки команды /start
async def start(update: Update, context) -> None:
await update.message.reply_text('Привет! Я чат-бот. Чем могу помочь?')

# Функция для обработки обычных сообщений
async def handle_message(update: Update, context):
user_id = update.effective_user.id
if user_id not in user_ids:
user_ids[user_id] = {'last_message': None, 'preferences': {}}
context_memory[user_id] = []

message_text = update.message.text
context_messages = context_memory[user_id]

# Добавляем новое сообщение в контекст
context_messages.append({'role': 'user', 'content': message_text})

# Ограничиваем историю контекста последними 8 сообщениями
context_memory[user_id] = context_messages[-8:]

try:
# Call the ollama.chat function with the context messages
response = ollama.chat(model='llama3:latest', messages=context_memory[user_id])
# Отправляем ответ пользователю
await update.message.reply_text(response['message']['content'])
except Exception as e:
logging.error(f"Error while getting response from ollama: {e}")
await update.message.reply_text('Произошла ошибка, попробуйте позже.')

# Основная функция
async def main() -> None:
application = ApplicationBuilder().token(TOKEN).build()

application.add_handler(CommandHandler('start', start))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

await application.run_polling()

if __name__ == '__main__':
import asyncio
asyncio.run(main())

В строку

response = ollama.chat(model='llama3', messages=context_memory[user_id])

нужно подставить имя нужной вам модели, которое можно посмотреть по команде

ollama list

10. Проверяем работу бота, запустив его в виртуальном окружении:

python./bot.py

и посмотрев ответы на ваши запросы из бота в Telegram.

Код не идеальный и его можно и нужно улучшать. Сам код был создан нами также с помощью LLM-модели (использовали llama3-8b-instruct), но есть идея протестировать и другие свободные модели, в том числе специализированные типа Codestral или Codellama-Python и сравнить между собой и с ChatGPT4o.

11. Если все работает и бот отвечает, создаем сервис для его запуска в системе:

tee /usr/lib/systemd/system/bot.service > /dev/null <<EOF

[Unit]
Description=Chat AI Bot Service
After=network-online.target

[Service]
Type=idle
Restart=always
RestartSec=3
User=root
WorkingDirectory=/home/user/
ExecStart=/home/user/venv/bin/python /home/user/bot.py

[Install]
WantedBy=default.target

EOF

12. Запускаем сервис.

sudo systemctl daemon-reload
sudo systemctl enable bot
sudo systemctl start bot

Что делать, если у вас нет компьютера с RTX картой от Nvidia

  • Вы можете запустить Ollama на CPU. Будет работать в разы медленнее, чем на GPU, но попробовать можно. Если у вас нет 8 Гб RTX видеокарты, вы все равно можете попробовать запустить чат-бот, но ollama будет работать в GPU-offload режиме с переносом части нагрузки на процессор.
  • C марта 2024 года существует версия Ollama для GPU от AMD. Как установить и настроить эту версию и какие видеокарты поддерживаются, читайте на этой странице.
  • Вы можете арендовать виртуальный сервер с GPU у нас. Подойдут сервера с GPU от Nvidia начиная с A4000.

Опубликуйте ваш комментарий

Required for comment verification
    27 июня 2024 г. 14:38 - Olga Blednova  модератор  
    Отличная статья
    5 июля 2024 г. 10:17 - Эдуард Демерчян   
    Я старался)