What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Бот генератор-мемов и стендапов в Telegram по изображению (FreeGPT, Blip-2, Aiogram 3)

Percent

Moderator
Moderator
Депозит
$0
Уникально для: runion
Написал: rand
Системные требования для запуски нейронки Blip-2: Хороший процессор, от 16GB озу, видеокарта NVIDIA (если обработку будете вести через GPU), у меня же видеокарта от AMD, я реализовал через CPU. (На линуксе вроде как есть возможность использовать pytorch через GPU AMD, но я не пробовал)

Всем привет уважаемые участники форума, решил написать по приколу бота генератора-мемов. Задумка такая, отправляем изображение, распознаем его нейросетью Blip-2 и возвращаем текст что изображено на изображении (скачать модель с датасетами можно по адресу: https://huggingface.co/Salesforce/blip2-opt-2.7b). Я же прикреплять её в zip не буду, слишком большой вес. После того как Blip 2 распознает изображение, возвращает промт, его же я и передаю для генерации мема FreeGPT (Можно адаптировать и под ChatGpt, но мне не хочется с ним заморачиваться из России) и накладываю сгенерированный текст мема на изображение через библиотеку Pillow.

Получается примерно так, обязательно вводим команду /start, выбираем кнопками что хотим сгенерировать (Стендап или мем) отправляем картинку в разрешении от 512 на 512 боту и получаем её обратно с подписанным мемом на изображении, или стендапом от FreeGPT (обязательный размер изображения от 512 на 512):
Спойлер: Изображение №1
1719318405500.png

Спойлер: Изображение №2
1719320451004.png


Версия Python 3.11, accelerate 0.31.0, Pillow 10.3.0, g4f 0.3.2.6, imgbbpy 0.1.3, aiogram 3.8.0, transformers 4.41.2, requests 2.32.3, curl-cffi 0.7.1

Для запуска требуется:

Bash: Скопировать в буфер обмена
Code:
pip install accelerate==0.31.0
pip install Pillow==10.3.0
pip install g4f==0.3.2.6
pip install imgbbpy==0.1.3
pip install aiogram==3.8.0
pip install transformers==4.41.2
pip install requests==2.32.3
pip install curl-cffi==0.7.1

bot.py:
Python: Скопировать в буфер обмена
Code:
###!!!Обязательно после установки всех библиотек сделать pip uninstall numpy, а потом pip install numpy==1.26.4
import imgbbpy
import g4f
from aiogram import Bot, Dispatcher, types, F, Router
from PIL import Image, ImageDraw, ImageFont
from transformers import Blip2Processor, Blip2ForConditionalGeneration
from transformers.image_utils import load_image
from aiogram.types import FSInputFile
from aiogram.filters import Command, StateFilter
from aiogram.types import Message
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup

# Объект бота
bot = Bot(token="7469496237:AAGOVA0lOvBr0t9L1ckbaybSGp0Ny555555")
# Диспетчер
dp = Dispatcher()
# Роутер
router = Router()
#Объявляем стэйты
class Mem(StatesGroup):
    mem_select = State()
# Создаем базу данных пользователей
user_dict: dict[int, dict[str, str | int | bool]] = {}


@dp.message(Command("start"))
async def cmd_start(message: Message, state: FSMContext):
    global slovo_prompt
    kb = [
        [types.KeyboardButton(text="Мем")],
        [types.KeyboardButton(text="Стендап")]
    ]
    keyboard = types.ReplyKeyboardMarkup(keyboard=kb)
    await message.answer("Что вам нужно сгенерировать, мем или стендап?", reply_markup=keyboard)
    await state.set_state(Mem.mem_select)
@dp.message(StateFilter(Mem.mem_select))
async def anceta_name(message: Message, state: FSMContext):
    await state.update_data(mem=message.text)
    user_dict[message.from_user.id] = await state.get_data()
    print(user_dict[message.from_user.id]["mem"])
    await message.answer("Загрузите изображение размером от 512 на 512 пикселей")
    #Состояние ожидания ввода возраста
    await state.clear()
@dp.message(F.photo)
async def download_photo(message: Message, bot: Bot):
    mem_select = user_dict[message.from_user.id]["mem"]
    print(mem_select)
    # Грузим изображение в на диск и указываем директорию
    await bot.download(
        message.photo[-1],
        destination=f"D:/Форум/Генератор мемов Aiogram/pythonProject1/tmp/{message.photo[-1].file_id}.jpg"
    )
    im_mem = Image.open(f"D:/Форум/Генератор мемов Aiogram/pythonProject1/tmp/{message.photo[-1].file_id}.jpg")
    # Выставляем условие на загрузку изображения размером от 512 на 512
    if im_mem.height >= 512 and im_mem.width >= 512:
        # Грузим изображение на хостинг картинок imgbb.com для последующей передачи картинки FreeGPT (Регистрируемся на сайте и получаем API key по адресу https://api.imgbb.com/)
        client = imgbbpy.SyncClient('dfa2776f3bb63ec6901f9d419311a3ae')  # Можете использовать мой токен, мне на него пофиг =)
        image = client.upload(file=f"D:/Форум/Генератор мемов Aiogram/pythonProject1/tmp/{message.photo[-1].file_id}.jpg") # Указываем путь до нашего изображения
        print(image.url)
        # Создаем переменную для передачи URL нейросетке
        image = image.url
        # Грузим изображение на хостинг картинок imgbb.com для последующей передачи картинки FreeGPT (Регистрируемся на сайте и получаем API key по адресу https://api.imgbb.com/)
    else:
        await message.answer("Ошибка: Загрузите изображение размером от 512 на 512 или больше.")
        return
    #### Распознаем изображение используя модель нейросети BLIP-2 на базе фреймворка PyTorch для передачи промта в FreeGpt (Я использую модель Salesforce/blip2-opt-2.7b на float16 "Системные требования 16GB ОЗУ, 10GB видеопамяти", модель можно запускать на CPU, подробно: https://huggingface.co/Salesforce/blip2-opt-2.7b, тамже можно и скачать все файлы модели
    # P.S. Есть более точная модель https://huggingface.co/Salesforce/blip2-opt-6.7b/tree/main но её я запускать не пробовал.
    # P.S.S pip install accelerate (Accelerate was created for PyTorch users who like to write the training loop of PyTorch models but are reluctant to write and maintain the boilerplate code needed to use multi-GPUs/TPU/fp16.)

    ### Если у тебя видеокарта Nvidia работающая на ядрах CUDA, раскоментируй этот код, так как я юзаю AMD, буду использовать обработку на CPU
    #processor = Blip2Processor.from_pretrained("D:/Форум/Генератор мемов Aiogram/pythonProject1/BLIP-2/")
    #model = Blip2ForConditionalGeneration.from_pretrained("D:/Форум/Генератор мемов Aiogram/pythonProject1/BLIP-2/", torch_dtype=torch.float16, device_map="auto")

    #img_url = image
    #raw_image = Image.open(requests.get(img_url, stream=True).raw).convert('RGB')

    #question = "Who or what is depicted in the picture?" #Наш промт нейросети
        ###Это строка для пользователей видеокарт NVIDIA, у меня же AMD
    #inputs = processor(raw_image, question, return_tensors="pt").to("cuda", torch.float16)
    #inputs = processor(raw_image, question, return_tensors="pt").to(device, torch.float16)
    #out = model.generate(**inputs)
    #print(processor.decode(out[0], skip_special_tokens=True).strip())
    ### Если у тебя видеокарта Nvidia работающая на ядрах CUDA, раскоментируй этот код, так как я юзаю AMD, буду использовать обработку на CPU

    ###(Если будешь использовать обработку на GPU удали или закомментируй этот блок)
    ###Обработка на CPU (Сначала делай pip uninstall torch, потом pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu), у меня съедало при обработке около 12 гигабайт оперы.
    await message.answer("Ожидайте до 60 секунд, идет генерация мема....")
    processor = Blip2Processor.from_pretrained("D:/Форум/Генератор мемов Aiogram/pythonProject1/BLIP-2/")
    model = Blip2ForConditionalGeneration.from_pretrained("D:/Форум/Генератор мемов Aiogram/pythonProject1/BLIP-2/")

    img_url = image
    raw_image = load_image(img_url)

    question = "a" #Можете задать точный промт, но в данном случае я запускаю завершение текста вместо вопроса


    inputs = processor(raw_image, question, return_tensors="pt")

    out = model.generate(**inputs)
    print(processor.decode(out[0], skip_special_tokens=True))
    text_prompt_mem = processor.decode(out[0], skip_special_tokens=True) #Создаем переменную для передачи фразы Free4GPT
    ###Обработка на CPU (Если будешь использовать обработку на GPU удали или закомментируй этот блок
    ##### Распознаем изображение используя модель нейросети BLIP-2

    ###Работаем с GPT4free
    try:
        response = await g4f.ChatCompletion.create_async(
            model=g4f.models.default,
            messages=[
                {"role": "user", "content": f"Придумай новый смешной короткий {mem_select} на основе этого текста: {text_prompt_mem}. Не пиши ничего кроме текста, не ставь кавычки, обязательно используй русский язык"}],
            provider=g4f.Provider.Blackbox,
        )
        chat_gpt_response = response
    except Exception as e:
        print(f"{g4f.Provider.Blackbox.__name__}:", e)
        chat_gpt_response = "Извините, произошла ошибка."

    print(chat_gpt_response)
    ###Работаем с GPT4free
    global mem_stroka_full
    ###Работаем со списком текста для правильного наложения на картинку в столбик
    if mem_select == "Мем":
        split_mem = chat_gpt_response.split() # Делим строки на подстроки, а потом собираем, можно сделать циклом, но я использую встроенные методы и функции python
        y = split_mem
        z = 10 # Делим список по срезам на 10 элементов, обычно длина мема не превышает 20 слов
        y1, y2 = y[:z], y[z:]
        #Собираем списки в строку
        mem_stroka_1 = " ".join(y1)
        mem_stroka_2 = " ".join(y2)
        mem_stroka_full = mem_stroka_1 + "\n" + mem_stroka_2 # Конкатинируем строку с отступом
        print(mem_stroka_full)
        ###Работаем со списком текста для правильного наложения на картинку
    elif mem_select == "Стендап":
        mem_stroka_full = chat_gpt_response

    ###Обрабатываем изображение через Pillow и накладываем текст мема
    if mem_select == "Мем":
        font = ImageFont.truetype('D:/Форум/Генератор мемов Aiogram/pythonProject1/fonts/impact.ttf', size=16)
        draw_text = ImageDraw.Draw(im_mem)
        draw_text.text(
                (im_mem.width/2, im_mem.height - im_mem.height/6),
                    mem_stroka_full,
                    anchor="mm",
                    # Добавляем шрифт к изображению, я использовал impact.ttf
                    font=font,
                    fill='#FFFFFF',
                    align="center",
                    stroke_width=1,
                    stroke_fill='#000000'
                    )
        im_mem.save(f"D:/Форум/Генератор мемов Aiogram/pythonProject1/output/{message.photo[-1].file_id}.jpg") #Сохраняем наше изображение для последующей отправки в Telegram бота
    elif mem_select == "Стендап":
        im_mem.save(f"D:/Форум/Генератор мемов Aiogram/pythonProject1/output/{message.photo[-1].file_id}.jpg")  # Сохраняем наше изображение для последующей отправки в Telegram бота
    ###Обрабатываем изображение через Pillow и накладываем текст мема

    ###Отправляем обратно изображение с мемом в ТГ
    try:
        image_from_pc = FSInputFile(f"D:/Форум/Генератор мемов Aiogram/pythonProject1/output/{message.photo[-1].file_id}.jpg") # Путь до созданного изображение
        await message.answer_photo(image_from_pc, caption=f"{mem_stroka_full}") # Возвращаем изображение с мемом
    except:
        await message.answer("Извините, произошла ошибка при генерации мема.")
    ###Отправляем обратно изображение с мемом в ТГ

try:
    print("Бот запущен.")
    dp.run_polling(bot)

except:
    print("Произошла ошибка при запуске бота!")

Видео по запуску и работе:



P.S. Все более детально расписано в комментариях к коду. Будут проблемы по запуску обращайтесь в ПМ.
P.S.S. В коде используется бесплатная нейронка на модели от провайдера BlackBox AI, была бы возможность заюзал бы ChatGpt 4, бот бы был поумнее.

Вложения​


  • bot_mem_generator_freegpt (1.0).zip
    191.6 КБ · Просмотры: 0
 
Top